バイト数を人間が読める文字列にフォーマットする慣用のScalaコードを探しています。これはファイルサイズをユーザーに表示するときに便利です。慣用のScalaを持つ人間が読める形式のバイト
たとえば、1000バイトは1.0 kB
と49134421234バイトから49.1 GB
にフォーマットする必要があります。
フォーマット機能のためのいくつかの要件:両方のSI(例えば、メガバイト)とIEC単位(例えば、メビバイト)
- として読めると慣用句Scala.js
バイト数を人間が読める文字列にフォーマットする慣用のScalaコードを探しています。これはファイルサイズをユーザーに表示するときに便利です。慣用のScalaを持つ人間が読める形式のバイト
たとえば、1000バイトは1.0 kB
と49134421234バイトから49.1 GB
にフォーマットする必要があります。
フォーマット機能のためのいくつかの要件:両方のSI(例えば、メガバイト)とIEC単位(例えば、メビバイト)
私のバージョンを経由して、ブラウザ内のライブラリ
/**
* Converts a number of bytes into a human-readable string
* such as `2.2 MB` or `8.0 EiB`.
*
* @param bytes the number of bytes we want to convert
* @param si if true, we use base 10 SI units where 1000 bytes are 1 kB.
* If false, we use base 2 IEC units where 1024 bytes are 1 KiB.
* @return the bytes as a human-readable string
*/
def humanReadableSize(bytes: Long, si: Boolean): String = {
// See https://en.wikipedia.org/wiki/Byte
val (baseValue, unitStrings) =
if (si)
(1000, Vector("B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"))
else
(1024, Vector("B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"))
def getExponent(curBytes: Long, baseValue: Int, curExponent: Int = 0): Int =
if (curBytes < baseValue) curExponent
else {
val newExponent = 1 + curExponent
getExponent(curBytes/(baseValue * newExponent), baseValue, newExponent)
}
val exponent = getExponent(bytes, baseValue)
val divisor = Math.pow(baseValue, exponent)
val unitString = unitStrings(exponent)
// Divide the bytes and show one digit after the decimal point
f"${bytes/divisor}%.1f $unitString"
}
使用例:
// Result: 1.0 kB
humanReadableSize(1000, si = true)
// Result: 1000.0 B
humanReadableSize(1000, si = false)
// Result: 10.0 kB
humanReadableSize(10000, si = true)
// Result: 9.8 KiB
humanReadableSize(10000, si = false)
// Result: 49.1 GB
humanReadableSize(49134421234L, si = true)
// Result: 45.8 GiB
humanReadableSize(49134421234L, si = false)
私は、それが上記のようにオプションで用意されていないようながら、それが迅速かつシンプルで、この代替バージョンを見つけました。
def bytesToString(size: Long): String = {
val TB = 1L << 40
val GB = 1L << 30
val MB = 1L << 20
val KB = 1L << 10
val (value, unit) = {
if (size >= 2*TB) {
(size.asInstanceOf[Double]/TB, "TB")
} else if (size >= 2*GB) {
(size.asInstanceOf[Double]/GB, "GB")
} else if (size >= 2*MB) {
(size.asInstanceOf[Double]/MB, "MB")
} else if (size >= 2*KB) {
(size.asInstanceOf[Double]/KB, "KB")
} else {
(size.asInstanceOf[Double], "B")
}
}
"%.1f %s".formatLocal(Locale.US, value, unit)}