Java - 将人类可读大小转换为字节

Dan*_*bes 9 java byte human-readable long-integer

我发现了很多关于将原始字节信息转换为人类可读格式的信息,但我需要做相反的事情,即将字符串"1.6 GB"转换为长值1717990000.是否内置/良好 - 这样做的定义方式,还是我几乎不得不自己动手?

[编辑]:这是我的第一次刺...

static class ByteFormat extends NumberFormat {
    @Override
    public StringBuffer format(double arg0, StringBuffer arg1, FieldPosition arg2) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public StringBuffer format(long arg0, StringBuffer arg1, FieldPosition arg2) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Number parse(String arg0, ParsePosition arg1) {
        return parse (arg0);
    }

    @Override
    public Number parse(String arg0) {
        int spaceNdx = arg0.indexOf(" ");
        double ret = Double.parseDouble(arg0.substring(0, spaceNdx));
        String unit = arg0.substring(spaceNdx + 1);
        int factor = 0;
        if (unit.equals("GB")) {
            factor = 1073741824;
        }
        else if (unit.equals("MB")) {
            factor = 1048576;
        }
        else if (unit.equals("KB")) {
            factor = 1024;
        }

        return ret * factor;
    }
}
Run Code Online (Sandbox Code Playgroud)

Utk*_*mir 11

Spring Framework 在 5.1 版中添加了一个DataSize类,该类允许将人类可读的数据大小解析为字节,并将它们格式化回人类可读的形式。可以在这里找到。

如果使用 Spring Framework,则可以升级到 >=5.1 并使用此类。否则你可以 c/p 它和相关的类(同时遵守许可证)。

然后你可以使用它:

DataSize dataSize = DataSize.parse("16GB");
System.out.println(dataSize.toBytes());
Run Code Online (Sandbox Code Playgroud)

将给出输出:

17179869184

但是,用于解析输入的模式

  • 不支持小数(因此,您可以使用1GB, 2GB, 1638MB,但不能使用1.6GB
  • 不支持空格(因此,您可以使用1GB但不能使用1 GB

我会建议坚持兼容性/易于维护的约定。但如果这不符合您的需要,您需要复制和编辑文件 - 这是一个很好的起点。


And*_*niy 5

我从来没有听说过这么有名的库,它实现了这样的文本解析实用程序方法。但是您的解决方案似乎离正确实施很近。

我想在您的代码中更正的唯一两件事是:

  1. Number parse(String arg0)由于其实用性质,将方法定义为静态

  2. factor每种类型的大小定义的s 定义为final static字段。

即它会是这样的:

private final static long KB_FACTOR = 1024;
private final static long MB_FACTOR = 1024 * KB_FACTOR;
private final static long GB_FACTOR = 1024 * MB_FACTOR;

public static double parse(String arg0) {
    int spaceNdx = arg0.indexOf(" ");
    double ret = Double.parseDouble(arg0.substring(0, spaceNdx));
    switch (arg0.substring(spaceNdx + 1)) {
        case "GB":
            return ret * GB_FACTOR;
        case "MB":
            return ret * MB_FACTOR;
        case "KB":
            return ret * KB_FACTOR;
    }
    return -1;
}
Run Code Online (Sandbox Code Playgroud)

  • 您的解决方案是将千字节与千字节混淆,将兆字节与兆字节混淆,将千兆字节与千兆字节混淆。 (2认同)

gil*_*ilz 5

Andremoniy 的答案的修订版,可以正确区分公斤和 kibi 等。

private final static long KB_FACTOR = 1000;
private final static long KIB_FACTOR = 1024;
private final static long MB_FACTOR = 1000 * KB_FACTOR;
private final static long MIB_FACTOR = 1024 * KIB_FACTOR;
private final static long GB_FACTOR = 1000 * MB_FACTOR;
private final static long GIB_FACTOR = 1024 * MIB_FACTOR;

public static double parse(String arg0) {
    int spaceNdx = arg0.indexOf(" ");
    double ret = Double.parseDouble(arg0.substring(0, spaceNdx));
    switch (arg0.substring(spaceNdx + 1)) {
        case "GB":
            return ret * GB_FACTOR;
        case "GiB":
            return ret * GIB_FACTOR;
        case "MB":
            return ret * MB_FACTOR;
        case "MiB":
            return ret * MIB_FACTOR;
        case "KB":
            return ret * KB_FACTOR;
        case "KiB":
            return ret * KIB_FACTOR;
    }
    return -1;
}
Run Code Online (Sandbox Code Playgroud)


Rob*_*bAu 5

全部在一个答案中,解析为long

public class SizeUtil {

    public static String units = "BKMGTPEZY";

    public static long parse(String arg0) {
        int spaceNdx = arg0.indexOf(" ");    
        double ret = Double.parseDouble(arg0.substring(0, spaceNdx));
        String unitString = arg0.substring(spaceNdx+1);
        int unitChar = unitString.charAt(0);
        int power = units.indexOf(unitChar);
        boolean isSi = unitString.indexOf('i')!=-1;
        int factor = 1024;
        if (isSi) 
        {
            factor = 1000;
        }

        return new Double(ret * Math.pow(factor, power)).longValue();
    }

    public static void main(String[] args) {
        System.out.println(parse("300.00 GiB")); // requires a space
        System.out.println(parse("300.00 GB"));
        System.out.println(parse("300.00 B"));
        System.out.println(parse("300 EB"));
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 通过查找字母的第一个索引,也可以在没有空格的情况下工作。 (2认同)