如何在Java中将字节大小转换为人类可读的格式?
比如1024应该变成“1 Kb”,1024*1024应该变成“1 Mb”。
我有点厌倦了为每个项目写这个实用方法。在Apache Commons中有这样的静态方法吗?
如何在Java中将字节大小转换为人类可读的格式?
比如1024应该变成“1 Kb”,1024*1024应该变成“1 Mb”。
我有点厌倦了为每个项目写这个实用方法。在Apache Commons中有这样的静态方法吗?
当前回答
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 "???";
}
其他回答
使用下面的函数来获得确切的信息。它是基于atm_cashwithdraw概念生成的。
getFullMemoryUnit(): Total: [123 MB], Max: [1 GB, 773 MB, 512 KB], Free: [120 MB, 409 KB, 304 Bytes]
public static String getFullMemoryUnit(long unit) {
long BYTE = 1024, KB = BYTE, MB = KB * KB, GB = MB * KB, TB = GB * KB;
long KILO_BYTE, MEGA_BYTE = 0, GIGA_BYTE = 0, TERA_BYTE = 0;
unit = Math.abs(unit);
StringBuffer buffer = new StringBuffer();
if ( unit / TB > 0 ) {
TERA_BYTE = (int) (unit / TB);
buffer.append(TERA_BYTE+" TB");
unit -= TERA_BYTE * TB;
}
if ( unit / GB > 0 ) {
GIGA_BYTE = (int) (unit / GB);
if (TERA_BYTE != 0) buffer.append(", ");
buffer.append(GIGA_BYTE+" GB");
unit %= GB;
}
if ( unit / MB > 0 ) {
MEGA_BYTE = (int) (unit / MB);
if (GIGA_BYTE != 0) buffer.append(", ");
buffer.append(MEGA_BYTE+" MB");
unit %= MB;
}
if ( unit / KB > 0 ) {
KILO_BYTE = (int) (unit / KB);
if (MEGA_BYTE != 0) buffer.append(", ");
buffer.append(KILO_BYTE+" KB");
unit %= KB;
}
if ( unit > 0 ) buffer.append(", "+unit+" Bytes");
return buffer.toString();
}
我刚刚修改了facebookarchive-StringUtils的代码以获得以下格式。与使用apache.hadoop-StringUtils时得到的格式相同
getMemoryUnit(): Total: [123.0 MB], Max: [1.8 GB], Free: [120.4 MB]
public static String getMemoryUnit(long bytes) {
DecimalFormat oneDecimal = new DecimalFormat("0.0");
float BYTE = 1024.0f, KB = BYTE, MB = KB * KB, GB = MB * KB, TB = GB * KB;
long absNumber = Math.abs(bytes);
double result = bytes;
String suffix = " Bytes";
if (absNumber < MB) {
result = bytes / KB;
suffix = " KB";
} else if (absNumber < GB) {
result = bytes / MB;
suffix = " MB";
} else if (absNumber < TB) {
result = bytes / GB;
suffix = " GB";
}
return oneDecimal.format(result) + suffix;
}
以上方法的使用示例:
public static void main(String[] args) {
Runtime runtime = Runtime.getRuntime();
int availableProcessors = runtime.availableProcessors();
long heapSize = Runtime.getRuntime().totalMemory();
long heapMaxSize = Runtime.getRuntime().maxMemory();
long heapFreeSize = Runtime.getRuntime().freeMemory();
System.out.format("Total: [%s], Max: [%s], Free: [%s]\n", heapSize, heapMaxSize, heapFreeSize);
System.out.format("getMemoryUnit(): Total: [%s], Max: [%s], Free: [%s]\n",
getMemoryUnit(heapSize), getMemoryUnit(heapMaxSize), getMemoryUnit(heapFreeSize));
System.out.format("getFullMemoryUnit(): Total: [%s], Max: [%s], Free: [%s]\n",
getFullMemoryUnit(heapSize), getFullMemoryUnit(heapMaxSize), getFullMemoryUnit(heapFreeSize));
}
字节来获取上面的格式
Total: [128974848], Max: [1884815360], Free: [126248240]
为了以人类可读的格式显示时间,请使用函数millisToShortDHMS(长持续时间)。
下面是上面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#项目时,这个问题/答案出现在谷歌搜索的顶部。
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等) 上面的代码是快速的,使用非常少的内存。基于在我个人的入门级云计算机上运行的基准测试,它是最快的(在这些情况下性能并不重要,但仍然如此) 以上代码是一个很好的答案的修改版本
你可以使用StringUtils的TraditionalBinarPrefix:
public static String humanReadableInt(long number) {
return TraditionalBinaryPrefix.long2String(number, ””, 1);
}