如何在Java中将字节大小转换为人类可读的格式?
比如1024应该变成“1 Kb”,1024*1024应该变成“1 Mb”。
我有点厌倦了为每个项目写这个实用方法。在Apache Commons中有这样的静态方法吗?
如何在Java中将字节大小转换为人类可读的格式?
比如1024应该变成“1 Kb”,1024*1024应该变成“1 Mb”。
我有点厌倦了为每个项目写这个实用方法。在Apache Commons中有这样的静态方法吗?
当前回答
有趣的事实:这里发布的原始代码片段是Stack Overflow上被复制最多的Java代码片段,它是有缺陷的。它被修好了,但却变得一团糟。 本文的完整故事:有史以来复制最多的堆栈溢出代码片段是有缺陷的!
来源:格式化字节大小到人类可读的格式|编程。指南
SI(1 k = 1,000)
public static String humanReadableByteCountSI(long bytes) {
if (-1000 < bytes && bytes < 1000) {
return bytes + " B";
}
CharacterIterator ci = new StringCharacterIterator("kMGTPE");
while (bytes <= -999_950 || bytes >= 999_950) {
bytes /= 1000;
ci.next();
}
return String.format("%.1f %cB", bytes / 1000.0, ci.current());
}
二进制(1's = 1,024)
public static String humanReadableByteCountBin(long bytes) {
long absB = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes);
if (absB < 1024) {
return bytes + " B";
}
long value = absB;
CharacterIterator ci = new StringCharacterIterator("KMGTPE");
for (int i = 40; i >= 0 && absB > 0xfffccccccccccccL >> i; i -= 10) {
value >>= 10;
ci.next();
}
value *= Long.signum(bytes);
return String.format("%.1f %ciB", value / 1024.0, ci.current());
}
示例输出:
SI BINARY
0: 0 B 0 B
27: 27 B 27 B
999: 999 B 999 B
1000: 1.0 kB 1000 B
1023: 1.0 kB 1023 B
1024: 1.0 kB 1.0 KiB
1728: 1.7 kB 1.7 KiB
110592: 110.6 kB 108.0 KiB
7077888: 7.1 MB 6.8 MiB
452984832: 453.0 MB 432.0 MiB
28991029248: 29.0 GB 27.0 GiB
1855425871872: 1.9 TB 1.7 TiB
9223372036854775807: 9.2 EB 8.0 EiB (Long.MAX_VALUE)
其他回答
filename=filedilg.getSelectedFile().getAbsolutePath();
File file=new File(filename);
String disp=FileUtils.byteCountToDisplaySize(file.length());
System.out.println("THE FILE PATH IS "+file+"THIS File SIZE IS IN MB "+disp);
Kotlin爱好者可以使用这个扩展:
fun Long.readableFormat(): String {
if (this <= 0 ) return "0"
val units = arrayOf("B", "kB", "MB", "GB", "TB")
val digitGroups = (log10(this.toDouble()) / log10(1024.0)).toInt()
return DecimalFormat("#,##0.#").format(this / 1024.0.pow(digitGroups.toDouble())).toString() + " " + units[digitGroups]
}
现在使用
val size : Long = 90836457
val readbleString = size.readableFormat()
另一种方法
val Long.formatSize : String
get() {
if (this <= 0) return "0"
val units = arrayOf("B", "kB", "MB", "GB", "TB")
val digitGroups = (log10(this.toDouble()) / log10(1024.0)).toInt()
return DecimalFormat("#,##0.#").format(this / 1024.0.pow(digitGroups.toDouble())).toString() + " " + units[digitGroups]
}
现在使用
val size : Long = 90836457
val readbleString = size.formatSize
下面是上面Java正确的共识答案的c# .NET等价版本 (下面还有一个代码更短的例子):
public static String BytesNumberToHumanReadableString(long bytes, bool SI1000orBinary1024)
{
int unit = SI1000orBinary1024 ? 1000 : 1024;
if (bytes < unit)
return bytes + " B";
int exp = (int)(Math.Log(bytes) / Math.Log(unit));
String pre = (SI1000orBinary1024 ? "kMGTPE" : "KMGTPE")[(exp - 1)] + (SI1000orBinary1024 ? "" : "i");
return String.Format("{0:F1} {1}B", bytes / Math.Pow(unit, exp), pre);
}
从技术上讲,如果我们坚持使用国际单位制,这个程序适用于任何常规的数字使用。专家们还给出了许多不错的答案。假设您正在对gridview上的数字进行数据绑定,有必要从它们中查看性能优化例程。
PS:这个帖子是因为当我在做一个c#项目时,这个问题/答案出现在谷歌搜索的顶部。
我最近问了同样的问题:
格式文件大小为MB, GB等。
虽然没有开箱即用的答案,但我可以接受这个解决方案:
private static final long K = 1024;
private static final long M = K * K;
private static final long G = M * K;
private static final long T = G * K;
public static String convertToStringRepresentation(final long value){
final long[] dividers = new long[] { T, G, M, K, 1 };
final String[] units = new String[] { "TB", "GB", "MB", "KB", "B" };
if(value < 1)
throw new IllegalArgumentException("Invalid file size: " + value);
String result = null;
for(int i = 0; i < dividers.length; i++){
final long divider = dividers[i];
if(value >= divider){
result = format(value, divider, units[i]);
break;
}
}
return result;
}
private static String format(final long value,
final long divider,
final String unit){
final double result =
divider > 1 ? (double) value / (double) divider : (double) value;
return new DecimalFormat("#,##0.#").format(result) + " " + unit;
}
测试代码:
public static void main(final String[] args){
final long[] l = new long[] { 1l, 4343l, 43434334l, 3563543743l };
for(final long ll : l){
System.out.println(convertToStringRepresentation(ll));
}
}
输出(在我的德语地区):
1 B
4,2 KB
41,4 MB
3,3 GB
我已经打开了一个问题,要求谷歌番石榴的这个功能。也许有人愿意支持它。
试试JSR 363。它的单元扩展模块,如Unicode CLDR(在GitHub: uom-systems中),为您完成所有这些。
你可以使用每个实现中包含的MetricPrefix或BinaryPrefix(与上面的一些例子相比),如果你在印度或附近的国家生活和工作,IndianPrefix(也在uom-系统的公共模块中)允许你使用和格式化“千万字节”或“Lakh字节”。