如何在Java中将字节大小转换为人类可读的格式?
比如1024应该变成“1 Kb”,1024*1024应该变成“1 Mb”。
我有点厌倦了为每个项目写这个实用方法。在Apache Commons中有这样的静态方法吗?
如何在Java中将字节大小转换为人类可读的格式?
比如1024应该变成“1 Kb”,1024*1024应该变成“1 Mb”。
我有点厌倦了为每个项目写这个实用方法。在Apache Commons中有这样的静态方法吗?
当前回答
我使用了一个比公认答案稍作修改的方法:
public static String formatFileSize(long bytes) {
if (bytes <= 0)
return "";
if (bytes < 1000)
return bytes + " B";
CharacterIterator ci = new StringCharacterIterator("kMGTPE");
while (bytes >= 99_999) {
bytes /= 1000;
ci.next();
}
return String.format(Locale.getDefault(), "%.1f %cB", bytes / 1000.0, ci.current());
}
因为我想看到另一个输出:
SI
0: <--------- instead of 0 B
27: 27 B
999: 999 B
1000: 1.0 kB
1023: 1.0 kB
1024: 1.0 kB
1728: 1.7 kB
110592: 0.1 MB <--------- instead of 110.6 kB
7077888: 7.1 MB
452984832: 0.5 GB <--------- instead of 453.0 MB
28991029248: 29.0 GB
其他回答
你可以使用StringUtils的TraditionalBinarPrefix:
public static String humanReadableInt(long number) {
return TraditionalBinaryPrefix.long2String(number, ””, 1);
}
我最近问了同样的问题:
格式文件大小为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
我已经打开了一个问题,要求谷歌番石榴的这个功能。也许有人愿意支持它。
String[] fileSizeUnits = {"bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
public String calculateProperFileSize(double bytes){
String sizeToReturn = "";
int index = 0;
for(index = 0; index < fileSizeUnits.length; index++){
if(bytes < 1024){
break;
}
bytes = bytes / 1024;
}
System.out.println("File size in proper format: " + bytes + " " + fileSizeUnits[index]);
sizeToReturn = String.valueOf(bytes) + " " + fileSizeUnits[index];
return sizeToReturn;
}
只需添加更多的文件单元(如果有任何缺失),你将看到单元大小达到该单元(如果你的文件有那么长):
下面是一个快速,简单和可读的代码片段来实现这一点:
/**
* Converts byte size to human readable strings (also declares useful constants)
*
* @see <a href="https://en.wikipedia.org/wiki/File_size">File size</a>
*/
@SuppressWarnings("SpellCheckingInspection")
public class HumanReadableSize {
public static final double
KILO = 1000L, // 1000 power 1 (10 power 3)
KIBI = 1024L, // 1024 power 1 (2 power 10)
MEGA = KILO * KILO, // 1000 power 2 (10 power 6)
MEBI = KIBI * KIBI, // 1024 power 2 (2 power 20)
GIGA = MEGA * KILO, // 1000 power 3 (10 power 9)
GIBI = MEBI * KIBI, // 1024 power 3 (2 power 30)
TERA = GIGA * KILO, // 1000 power 4 (10 power 12)
TEBI = GIBI * KIBI, // 1024 power 4 (2 power 40)
PETA = TERA * KILO, // 1000 power 5 (10 power 15)
PEBI = TEBI * KIBI, // 1024 power 5 (2 power 50)
EXA = PETA * KILO, // 1000 power 6 (10 power 18)
EXBI = PEBI * KIBI; // 1024 power 6 (2 power 60)
private static final DecimalFormat df = new DecimalFormat("#.##");
public static String binaryBased(long size) {
if (size < 0) {
throw new IllegalArgumentException("Argument cannot be negative");
} else if (size < KIBI) {
return df.format(size).concat("B");
} else if (size < MEBI) {
return df.format(size / KIBI).concat("KiB");
} else if (size < GIBI) {
return df.format(size / MEBI).concat("MiB");
} else if (size < TEBI) {
return df.format(size / GIBI).concat("GiB");
} else if (size < PEBI) {
return df.format(size / TEBI).concat("TiB");
} else if (size < EXBI) {
return df.format(size / PEBI).concat("PiB");
} else {
return df.format(size / EXBI).concat("EiB");
}
}
public static String decimalBased(long size) {
if (size < 0) {
throw new IllegalArgumentException("Argument cannot be negative");
} else if (size < KILO) {
return df.format(size).concat("B");
} else if (size < MEGA) {
return df.format(size / KILO).concat("KB");
} else if (size < GIGA) {
return df.format(size / MEGA).concat("MB");
} else if (size < TERA) {
return df.format(size / GIGA).concat("GB");
} else if (size < PETA) {
return df.format(size / TERA).concat("TB");
} else if (size < EXA) {
return df.format(size / PETA).concat("PB");
} else {
return df.format(size / EXA).concat("EB");
}
}
}
注意:
上面的代码冗长而简单。 它不使用循环(循环应该只在您不知道在编译期间需要迭代多少次时使用) 它不会进行不必要的库调用(StringBuilder, Math等) 上面的代码是快速的,使用非常少的内存。基于在我个人的入门级云计算机上运行的基准测试,它是最快的(在这些情况下性能并不重要,但仍然如此) 以上代码是一个很好的答案的修改版本
public String humanReadable(long size) {
long limit = 10 * 1024;
long limit2 = limit * 2 - 1;
String negative = "";
if(size < 0) {
negative = "-";
size = Math.abs(size);
}
if(size < limit) {
return String.format("%s%s bytes", negative, size);
} else {
size = Math.round((double) size / 1024);
if (size < limit2) {
return String.format("%s%s kB", negative, size);
} else {
size = Math.round((double)size / 1024);
if (size < limit2) {
return String.format("%s%s MB", negative, size);
} else {
size = Math.round((double)size / 1024);
if (size < limit2) {
return String.format("%s%s GB", negative, size);
} else {
size = Math.round((double)size / 1024);
return String.format("%s%s TB", negative, size);
}
}
}
}
}