2017-08-25 3 views
1

Je suis à la recherche de code Scala idiomatique qui met en forme un nombre d'octets dans une chaîne lisible par l'homme qui est utile lors de l'affichage des tailles de fichiers pour les utilisateurs.octets dans un format lisible par l'homme avec idiomatique Scala

Par exemple, 1000 octets doivent être formatés à 1.0 kB et 49134421234 octets à 49.1 GB.

Certaines exigences de la fonction de mise en forme:

  • Comme lisible et idiomatiques possible
  • fonctionne avec les SI (par exemple, méga-octet) et les unités de la CEI (par exemple, mebibyte)
  • aucune dépendance externe bibliothèques
  • Executable dans un navigateur via Scala.js

Répondre

2

Ma version:

/** 
    * 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" 
} 

Exemples d'utilisation:

// 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) 
0

Je trouve cette version alternative, alors qu'il est pas aussi que optionné ce qui précède, il est rapide et simple.

Source Link

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