1 * 1024 * 1024
で1メガバイト、みたいなやつをよく見る。
コードレビューしていると、1000
だったり 1024
だったり、気を利かせて 1_024
と書かれていたり、たまに 124
とか 1240
とタイポしていたりと、結構揺らぎがち。また、KB/MB/GBかKiB/MiB/GiBか、みたいな議論になったりすることもあって面倒。
TimeUnit
のように、Javaで単位をわかりやすくできるライブラリはないかと思い、調べたのでメモ。
SpringのDataSize
Springに、各バイト単位を変換する DataSize
、および単位自体を表す列挙型の DataUnit
があった。
DataSize#of...bytes(long)
メソッドで DataSize
インスタンスを生成し、 to...Bytes()
で指定した単位の long
に変換する。また、 DataSize#parse(CharSequence)
で文字列の解析も可能。
DataUnit
の値名は KILOBYTES
, MEGABYTES
, GIGABYTES
だが、それぞれ2の10乗、20乗、30乗なので、 long
値は 1,024
, 1,048,576
, 1,073,741,824
となる。
// 単位系がわかっている場合、それに応じたofメソッドを使用 assert DataSize.ofMegabytes(1).toBytes() == 1 * 1024 * 1024; // of(long, DataUnit)で、任意の単位に変換可能 assert DataSize.of(2, DataUnit.GIGABYTES).toMegabytes() == 2 * 1024; // parse(CharSequence[, DataUnit])で文字列を解析 assert DataSize.parse("20MB").toBytes() == 20 * 1024 * 1024;
Apache Commons
Commons IOの FileUtils に、各単位の long
および BigInteger
が static
で宣言されている。
ONE_KB
, ONE_MB
, ONE_GB
などあるが、 DataSize
と同様、それぞれ 1,024
, 1,048,576
, 1,073,741,824
となる。
FileUtils.byteCountToDisplaySize(long)
というメソッドで、バイト数を文字列に変換できるが、小数点以下が無視されるので扱いづらい。
その他
byteunits
というライブラリもあった。こちらは KB
と KiB
などを区別する模様。
振り返り
今日のJava開発であれば、Springはだいたい使っていると思うので、 DataSize
を使っておけばシンプルになりそう。
また、SpringもCommonsも1024の倍数をKB、MB、GBとして使っているので、下手にKiBなど使わず、KBとかにしておくのが無難かと思った。
余談
以下のスタックオーバーフローの記事で、数値から文字列に変換するスニペットが記載されている。
どうも、スタックオーバーフローで最もコピーされたスニペットらしいが、間違っていた模様。