4

解析したいファイルサイズがたくさんあります。これらは現在、GB 単位でのみ表示されます。以下にいくつかのサンプルを示します。

  • 1.2GB
  • 2.4GB

バイトファイルサイズを値に保存する必要があると思いLongますが、それを理解できないようです。これが私がやっている方法です:

System.out.println(Float.parseFloat("1.2GB".replace("GB", ""))* 1024L * 1024L * 1024L);

Floatこれは、として表示される値を返します1.28849024E9Longファイルサイズの表現をバイト単位で取得するにはどうすればよいですか。

数値データ型について少し混乱しています。ありがとう。

4

7 に答える 7

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");
于 2012-08-23T11:34:03.467 に答える
8

この関数は、より一般的なソリューションを提供します。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);
}
于 2012-08-23T11:45:46.557 に答える
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
于 2012-08-23T13:08:06.733 に答える
1

groovy の使用がオプションの場合、次のバージョンがあります。

  • 後置されていない文字列を処理します (つまり、数字 "1234" のみ)
  • スペースとコンマを処理します (「12,234B」または「12 234kB」など)
  • 入力文字列の解析に失敗した場合、やや説明的な例外をスローします
  • 間違った大文字と小文字の接頭辞とバイト インジケータを処理します。これは良い考えではないと主張することができます。私の特定のユースケースでは、不正確なデータが得られることが多いため、アルゴリズムのルールを多少緩和すると便利です。

コード:

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") }

このメソッドは、読みやすさのために最適化されていない可能性があります。コードを簡潔に保ちながら、すべてのエッジケースを取得しようとするのは楽しいことでした.

于 2015-10-15T11:52:01.227 に答える
1

を使用するFloatと、精度が失われる危険があります。

代わりに を使用することもできますBigDecimal

于 2012-08-23T11:34:54.623 に答える
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());
}
于 2012-08-23T11:45:42.237 に答える
0

出力する前に、Float 値を Long 値にキャストできます。

于 2012-08-23T11:34:39.220 に答える