我有一堆文件大小,我想解析。这些目前仅在GB中。以下是一些示例:
我认为我应该将我的字节文件大小存储在Long
值中,但我似乎无法弄明白。以下是我的表现:
System.out.println(Float.parseFloat("1.2GB".replace("GB", ""))* 1024L * 1024L * 1024L);
这将返回Float
值,该值显示为1.28849024E9
。如何以字节为单位获取文件大小的Long
表示。
我对数字数据类型感到困惑。感谢。
答案 0 :(得分:9)
改为使用BigDecimal
:
BigDecimal bytes = new BigDecimal("1.2GB".replace("GB", ""));
bytes = bytes.multiply(BigDecimal.valueOf(1024).pow(3));
long value = bytes.longValue();
您可以将其放入方法中:
public static long toBytes(String filesize) {
long returnValue = -1;
Pattern patt = Pattern.compile("([\\d.]+)([GMK]B)", Pattern.CASE_INSENSITIVE);
Matcher matcher = patt.matcher(filesize);
Map<String, Integer> powerMap = new HashMap<String, Integer>();
powerMap.put("GB", 3);
powerMap.put("MB", 2);
powerMap.put("KB", 1);
if (matcher.find()) {
String number = matcher.group(1);
int pow = powerMap.get(matcher.group(2).toUpperCase());
BigDecimal bytes = new BigDecimal(number);
bytes = bytes.multiply(BigDecimal.valueOf(1024).pow(pow));
returnValue = bytes.longValue();
}
return returnValue;
}
并称之为:
long bytes = toBytes("1.2GB");
答案 1 :(得分:7)
此功能将为您提供更通用的解决方案。它涵盖GB,MB和KB,并允许小数分隔符使用逗号和点。如果输入一个普通整数,它也会传递它。
public static long parseFilesize(String in) {
in = in.trim();
in = in.replaceAll(",",".");
try { return Long.parseLong(in); } catch (NumberFormatException e) {}
final Matcher m = Pattern.compile("([\\d.,]+)\\s*(\\w)").matcher(in);
m.find();
int scale = 1;
switch (m.group(2).charAt(0)) {
case 'G' : scale *= 1024;
case 'M' : scale *= 1024;
case 'K' : scale *= 1024; break;
default: throw new IllegalArgumentException();
}
return Math.round(Double.parseDouble(m.group(1)) * scale);
}
答案 2 :(得分:2)
不使用BigDecimal的较短版本。
public static long parseSize(String text) {
double d = Double.parseDouble(text.replaceAll("[GMK]B$", ""));
long l = Math.round(d * 1024 * 1024 * 1024L);
switch (text.charAt(Math.max(0, text.length() - 2))) {
default: l /= 1024;
case 'K': l /= 1024;
case 'M': l /= 1024;
case 'G': return l;
}
}
for (String s : "1.2GB 2.4GB 3.75MB 1.28KB 9".split(" "))
System.out.println(s + " = " + parseSize(s));
打印
1.2GB = 1288490189
2.4GB = 2576980378
3.75MB = 3932160
1.28KB = 1310
9 = 9
1.2884901888E9
答案 3 :(得分:1)
如果您使用Float
,则可能会失去精确度。
替代方案可能是使用BigDecimal
。
答案 4 :(得分:1)
这样的事情怎么样:
String sizeStr = "1.2GB";
Double base = 1024*Double.parseDouble(sizeStr.replaceAll("[GM]B",""));
final long sizeBytes;
if ( sizeStr.endsWith("GB") ) {
sizeBytes = 1024*1024*base.longValue());
}
else {
sizeBytes = 1024*base.longValue());
}
答案 5 :(得分:1)
如果使用groovy是一个选项,这里有一个版本:
代码:
import static groovy.test.GroovyAssert.shouldFail
long toBytes(String size) {
def matcher = size?.replaceAll(/[, ]/, '') =~ /(?i)^([\d.,]+)([PTGMK]?B)?$/
if (!matcher) throw new IllegalArgumentException("Can not parse size string '${size}'")
(matcher[0][1] as BigDecimal) * 1024**[PB:5, TB:4, GB:3, MB:2, KB:1].withDefault {0}[matcher[0][2]?.toUpperCase()]
}
assert toBytes(" 112 ") == 112
assert toBytes("112") == 112
assert toBytes("123456789") == 123456789
assert toBytes("1B") == 1
assert toBytes("1KB") == 1024
assert toBytes("300MB") == 300g*1024*1024
assert toBytes("1.2mb") == 1.2g*1024*1024 as Long
assert toBytes("123 456kB") == 123456g*1024
assert toBytes("123,456B") == 123456
assert toBytes("1.5GB") == 1.5g*1024*1024*1024
assert toBytes("300MB") == 300g*1024*1024
assert toBytes("512GB") == 512g*1024*1024*1024
assert toBytes("1Tb") == 1024g*1024*1024*1024
assert toBytes("1PB") == 1024g*1024*1024*1024*1024
def checkFailure = { c ->
assert shouldFail(c).message.startsWith("Can not parse size string")
}
checkFailure { toBytes(null) }
checkFailure { toBytes("") }
checkFailure { toBytes("x112") }
checkFailure { toBytes("112x") }
checkFailure { toBytes("11x2") }
该方法可能未针对可读性进行优化。尝试在保持代码简洁的同时处理所有边缘情况时有一些乐趣。
答案 6 :(得分:0)
您可以在打印之前将Float值转换为Long值。