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

我发现了很多关于将原始字节信息转换为人类可读格式的信息,但我需要做相反的事情,即将字符串“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; } } 

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

我想在你的代码中纠正的唯一两件事是:

  1. 由于其实用性,define方法将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; } 

安德莫尼的答案的修订版,正确区分公斤和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; } 

一个答案,解析为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")); } } 

我知道这要晚得多,但我正在寻找一个类似的function,它也考虑了SI前缀 。 所以我自己创建了一个,我认为它可能对其他人有用。

 public static String units = "KMGTPE"; /** * Converts from human readable to byte format * @param number The number value of the amount to convert * @param unit The unit: B, KB, MB, GB, TB, PB, EB * @param si Si prefix * @return byte value */ public static double parse(double number, String unit, boolean si) { String identifier = unit.substring(0, 1); int index = units.indexOf(identifier); //not already in bytes if (index!=-1) { for (int i = 0; i <= index; i++) number = number * (si ? 1000 : 1024); } return number; } 

我确信这也可能与递归有关。 打扰太简单了......

也可以使用以下方法并使其成为通用方法,而不依赖于空格字符进行解析。

感谢@RobAu的上述提示。 添加了一个新方法来获取字符串中第一个字母的索引,并更改了解析方法以基于此新方法获取索引。 我保留了原始的解析方法并添加了一个新的parseAny方法,因此可以比较结果。 希望它可以帮到某人。

另外,感谢indexOf方法的这个答案 – https://stackoverflow.com/a/11214786/6385674

 public class ConversionUtil { 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(); } /** @return index of pattern in s or -1, if not found */ public static int indexOf(Pattern pattern, String s) { Matcher matcher = pattern.matcher(s); return matcher.find() ? matcher.start() : -1; } public static long parseAny(String arg0) { int index = indexOf(Pattern.compile("[A-Za-z]"), arg0); double ret = Double.parseDouble(arg0.substring(0, index)); String unitString = arg0.substring(index); 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")); System.out.println(parseAny("300.00 GiB")); System.out.println(parseAny("300M")); } }