如何在Java中将字节大小转换为人类可读的格式?
比如1024应该变成“1 Kb”,1024*1024应该变成“1 Mb”。
我有点厌倦了为每个项目写这个实用方法。在Apache Commons中有这样的静态方法吗?
如何在Java中将字节大小转换为人类可读的格式?
比如1024应该变成“1 Kb”,1024*1024应该变成“1 Mb”。
我有点厌倦了为每个项目写这个实用方法。在Apache Commons中有这样的静态方法吗?
当前回答
你可以使用StringUtils的TraditionalBinarPrefix:
public static String humanReadableInt(long number) {
return TraditionalBinaryPrefix.long2String(number, ””, 1);
}
其他回答
我们可以完全避免使用缓慢的Math.pow()和Math.log()方法,而不会牺牲简单性,因为单位之间的因子(例如,B, KB, MB等)是1024,即2^10。Long类有一个方便的numberofleadingzero()方法,我们可以用它来告诉大小值落在哪个单元中。
重点:大小单位的距离为10位(1024 = 2^10),这意味着最高位的位置-换句话说,前导零的数量-相差10(字节= KB*1024, KB = MB*1024,等等)。
前导零数与大小单位的相关性:
# of leading 0's | Size unit |
---|---|
>53 | B (Bytes) |
>43 | KB |
>33 | MB |
>23 | GB |
>13 | TB |
>3 | PB |
<=3 | EB |
最终代码:
public static String formatSize(long v) {
if (v < 1024) return v + " B";
int z = (63 - Long.numberOfLeadingZeros(v)) / 10;
return String.format("%.1f %sB", (double)v / (1L << (z*10)), " KMGTPE".charAt(z));
}
public static String floatForm (double d)
{
return new DecimalFormat("#.##").format(d);
}
public static String bytesToHuman (long size)
{
long Kb = 1 * 1024;
long Mb = Kb * 1024;
long Gb = Mb * 1024;
long Tb = Gb * 1024;
long Pb = Tb * 1024;
long Eb = Pb * 1024;
if (size < Kb) return floatForm( size ) + " byte";
if (size >= Kb && size < Mb) return floatForm((double)size / Kb) + " Kb";
if (size >= Mb && size < Gb) return floatForm((double)size / Mb) + " Mb";
if (size >= Gb && size < Tb) return floatForm((double)size / Gb) + " Gb";
if (size >= Tb && size < Pb) return floatForm((double)size / Tb) + " Tb";
if (size >= Pb && size < Eb) return floatForm((double)size / Pb) + " Pb";
if (size >= Eb) return floatForm((double)size / Eb) + " Eb";
return "???";
}
现在有一个包含单元格式的库可用。我把它添加到triava库,因为唯一的其他现有库似乎是Android的。
它可以格式化数字与任意精度,在3个不同的系统(SI, IEC, JEDEC)和各种输出选项。下面是来自triava单元测试的一些代码示例:
UnitFormatter.formatAsUnit(1126, UnitSystem.SI, "B");
// = "1.13kB"
UnitFormatter.formatAsUnit(2094, UnitSystem.IEC, "B");
// = "2.04KiB"
打印精确的千克,百万值(这里用W =瓦特):
UnitFormatter.formatAsUnits(12_000_678, UnitSystem.SI, "W", ", ");
// = "12MW, 678W"
你可以传递一个DecimalFormat来定制输出:
UnitFormatter.formatAsUnit(2085, UnitSystem.IEC, "B", new DecimalFormat("0.0000"));
// = "2.0361KiB"
对于kilo或mega值的任意操作,您可以将它们拆分为组件:
UnitComponent uc = new UnitComponent(123_345_567_789L, UnitSystem.SI);
int kilos = uc.kilo(); // 567
int gigas = uc.giga(); // 123
也许你可以使用下面的代码(在c#中):
long Kb = 1024;
long Mb = Kb * 1024;
long Gb = Mb * 1024;
long Tb = Gb * 1024;
long Pb = Tb * 1024;
long Eb = Pb * 1024;
if (size < Kb) return size.ToString() + " byte";
if (size < Mb) return (size / Kb).ToString("###.##") + " Kb.";
if (size < Gb) return (size / Mb).ToString("###.##") + " Mb.";
if (size < Tb) return (size / Gb).ToString("###.##") + " Gb.";
if (size < Pb) return (size / Tb).ToString("###.##") + " Tb.";
if (size < Eb) return (size / Pb).ToString("###.##") + " Pb.";
if (size >= Eb) return (size / Eb).ToString("###.##") + " Eb.";
return "invalid size";
试试JSR 363。它的单元扩展模块,如Unicode CLDR(在GitHub: uom-systems中),为您完成所有这些。
你可以使用每个实现中包含的MetricPrefix或BinaryPrefix(与上面的一些例子相比),如果你在印度或附近的国家生活和工作,IndianPrefix(也在uom-系统的公共模块中)允许你使用和格式化“千万字节”或“Lakh字节”。