public interface IUnits {
public String format(long size, String pattern);
public long getUnitSize();
}
创建StorageUnits类:
import java.text.DecimalFormat;
public class StorageUnits {
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;
enum Unit implements IUnits {
TERA_BYTE {
@Override
public String format(long size, String pattern) {
return format(size, getUnitSize(), "TB", pattern);
}
@Override
public long getUnitSize() {
return T;
}
@Override
public String toString() {
return "Terabytes";
}
},
GIGA_BYTE {
@Override
public String format(long size, String pattern) {
return format(size, getUnitSize(), "GB", pattern);
}
@Override
public long getUnitSize() {
return G;
}
@Override
public String toString() {
return "Gigabytes";
}
},
MEGA_BYTE {
@Override
public String format(long size, String pattern) {
return format(size, getUnitSize(), "MB", pattern);
}
@Override
public long getUnitSize() {
return M;
}
@Override
public String toString() {
return "Megabytes";
}
},
KILO_BYTE {
@Override
public String format(long size, String pattern) {
return format(size, getUnitSize(), "kB", pattern);
}
@Override
public long getUnitSize() {
return K;
}
@Override
public String toString() {
return "Kilobytes";
}
};
String format(long size, long base, String unit, String pattern) {
return new DecimalFormat(pattern).format(
Long.valueOf(size).doubleValue() / Long.valueOf(base).doubleValue()
) + unit;
}
}
public static String format(long size, String pattern) {
for(Unit unit : Unit.values()) {
if(size >= unit.getUnitSize()) {
return unit.format(size, pattern);
}
}
return ("???(" + size + ")???");
}
public static String format(long size) {
return format(size, "#,##0.#");
}
}
叫它:
class Main {
public static void main(String... args) {
System.out.println(StorageUnits.format(21885));
System.out.println(StorageUnits.format(2188121545L));
}
}
private static final String[] SI_UNITS = { "B", "kB", "MB", "GB", "TB", "PB", "EB" };
private static final String[] BINARY_UNITS = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB" };
public static String humanReadableByteCount(final long bytes, final boolean useSIUnits, final Locale locale)
{
final String[] units = useSIUnits ? SI_UNITS : BINARY_UNITS;
final int base = useSIUnits ? 1000 : 1024;
// When using the smallest unit no decimal point is needed, because it's the exact number.
if (bytes < base) {
return bytes + " " + units[0];
}
final int exponent = (int) (Math.log(bytes) / Math.log(base));
final String unit = units[exponent];
return String.format(locale, "%.1f %s", bytes / Math.pow(base, exponent), unit);
}
/**
* formats the bytes to a human readable format
*
* @param si true if each kilo==1000, false if kilo==1024
*/
@SuppressLint("DefaultLocale")
public static String humanReadableByteCount(final long bytes,final boolean si)
{
final int unit=si ? 1000 : 1024;
if(bytes<unit)
return bytes+" B";
double result=bytes;
final String unitsToUse=(si ? "k" : "K")+"MGTPE";
int i=0;
final int unitsCount=unitsToUse.length();
while(true)
{
result/=unit;
if(result<unit)
break;
// check if we can go further:
if(i==unitsCount-1)
break;
++i;
}
final StringBuilder sb=new StringBuilder(9);
sb.append(String.format("%.1f ",result));
sb.append(unitsToUse.charAt(i));
if(si)
sb.append('B');
else sb.append('i').append('B');
final String resultStr=sb.toString();
return resultStr;
}
2
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);
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));
}
}
20 回答
在偶然的情况下,它可以节省一些时间,或者只是为了一点乐趣,这里是Go版本 . 为简单起见,我只包含了二进制输出案例 .
你可以使用StringUtils的
TraditionalBinarPrefix
:如果您的项目可以依赖
org.apache.commons.io
,FileUtils.byteCountToDisplaySize(long size)
将起作用 .JavaDoc for this method
我知道现在更新这篇文章已经太晚了!但我对此有一些乐趣:
创建一个界面:
创建StorageUnits类:
叫它:
输出:
只需添加更多文件单元(如果有任何缺失),您将看到单元大小达到该单位(如果您的文件有那么长的长度)System.out.println(“文件大小格式正确:”bytes“”fileSizeUnits [index] ); sizeToReturn = String.valueOf(bytes)“”fileSizeUnits [index]; return sizeToReturn; }
这是aioobe's answer的修改版本 .
变化:
Locale
参数,因为某些语言使用.
和其他,
作为小数点 .人类可读的代码
你试过JSR 363吗?它的单元扩展模块,如Unicode CLDR(在GitHub: uom-systems中)为您完成所有这些 .
您可以使用
MetricPrefix
包含在每个实现中或BinaryPrefix
(与上面的一些示例相比),如果您是在印度或附近国家生活和工作,IndianPrefix
(也在uom系统的通用模块中)允许您使用和格式化"Crore Bytes"或"Lakh Bytes" .Byte Units允许你这样做:
我写了另一个名为storage-units的库,允许你这样做:
如果您想强制某个单位,请执行以下操作:
这是我的去处(没有循环并处理SI单位和二进制单位):
输出示例:
相关文章:Java: Formatting byte size to human readable format
现在有一个可用的库包含单元格式 . 我将它添加到triava库中,因为唯一的其他现有库似乎是Android的库 .
它可以在3种不同的系统(SI,IEC,JEDEC)和各种输出选项中以任意精度格式化数字 . 以下是triava unit tests中的一些代码示例:
打印精确千克,超值(此处W =瓦特):
您可以传递DecimalFormat来自定义输出:
对于kilo或mega值的任意操作,您可以将它们拆分为组件:
Use Android builtin Class
对于Android,有一个类Formatter . 就像代码一样,你就完成了 .
它就像
formatFileSize()
,但试图产生更短的数字(显示更少的小数) .格式化内容大小为字节,千字节,兆字节等形式 .
如果您使用Android,则只需使用Formatter.formatFileSize()即可 .
另类,这是基于this popular post的解决方案:
我们可以完全避免使用慢速
Math.pow()
和Math.log()
方法而不牺牲简单性,因为单位之间的因子(例如B,KB,MB等)是1024,即2 ^ 10 .Long
类有一个方便的numberOfLeadingZeros()
方法,我们可以用它来判断大小值属于哪个单位 .Key point: 大小单位的距离为10位(1024 = 2 ^ 10),这意味着最高1位的位置 - 或者换言之,前导零的数量 - 相差10(字节= KB * 1024,KB = MB * 1024)等等 . ) .
Correlation between number of leading zeros and size unit:
The final code:
我最近问了同一个问题:
Format file size as MB, GB etc
虽然没有开箱即用的答案,但我可以接受解决方案:
测试代码:
输出(在我的德语区域设置上):
编辑:我已经打开Issue requesting this functionality for Google Guava . 也许有人会关心它 .
也许你可以使用这个代码(在C#中):
这是上面Java正确的共识答案的C#.net等价物 . (下面还有另一个代码更短的代码)
从技术上讲,如果我们坚持SI单位,这个例程适用于任何经常使用的数字 . 专家还有许多其他好的答案 . 假设您正在对gridviews上的数字进行数据绑定,那么从它们中检查性能优化的例程是值得的 .
PS:发布是因为当我在做C#项目时,这个问题/答案在谷歌搜索中排在首位 .