356 Stimmen

Konvertierung der Dateigröße in Bytes in eine für Menschen lesbare Zeichenfolge

Ich verwende diese Funktion, um eine Dateigröße in Bytes in eine für Menschen lesbare Dateigröße zu konvertieren:

function getReadableFileSizeString(fileSizeInBytes) {
  var i = -1;
  var byteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB'];
  do {
    fileSizeInBytes /= 1024;
    i++;
  } while (fileSizeInBytes > 1024);

  return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
}

console.log(getReadableFileSizeString(1551859712)); // output is "1.4 GB"

Es scheint jedoch, dass dies nicht zu 100 % richtig ist. Zum Beispiel:

getReadableFileSizeString(1551859712); // output is "1.4 GB"

Sollte das nicht sein "1.5 GB" ? Es scheint, als würde die Division durch 1024 an Präzision verlieren. Verstehe ich etwas völlig falsch oder gibt es einen besseren Weg, dies zu tun?

557voto

mpen Punkte 253762

Hier ist einer, den ich geschrieben habe:

/**
 * Format bytes as human-readable text.
 * 
 * @param bytes Number of bytes.
 * @param si True to use metric (SI) units, aka powers of 1000. False to use 
 *           binary (IEC), aka powers of 1024.
 * @param dp Number of decimal places to display.
 * 
 * @return Formatted string.
 */
function humanFileSize(bytes, si=false, dp=1) {
  const thresh = si ? 1000 : 1024;

  if (Math.abs(bytes) < thresh) {
    return bytes + ' B';
  }

  const units = si 
    ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] 
    : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
  let u = -1;
  const r = 10**dp;

  do {
    bytes /= thresh;
    ++u;
  } while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1);

  return bytes.toFixed(dp) + ' ' + units[u];
}

console.log(humanFileSize(1551859712))  // 1.4 GiB
console.log(humanFileSize(5000, true))  // 5.0 kB
console.log(humanFileSize(5000, false))  // 4.9 KiB
console.log(humanFileSize(-10000000000000000000000000000))  // -8271.8 YiB
console.log(humanFileSize(999949, true))  // 999.9 kB
console.log(humanFileSize(999950, true))  // 1.0 MB
console.log(humanFileSize(999950, true, 2))  // 999.95 kB
console.log(humanFileSize(999500, true, 0))  // 1 MB

170voto

Andrew V. Punkte 1569

Eine weitere Ausführungsform der Berechnung

function humanFileSize(size) {
    var i = size == 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024));
    return (size / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
}

66voto

Neil Punkte 52506

Es hängt davon ab, ob Sie die binäre oder dezimale Konvention verwenden wollen.

Der Arbeitsspeicher beispielsweise wird immer binär gemessen, so dass 1551859712 als ~1,4GiB korrekt wäre.

Andererseits verwenden die Festplattenhersteller gerne das Dezimalsystem, so dass sie von ~1,6 GB sprechen würden.

Und zur Verwirrung sei gesagt, dass Disketten eine Mischung aus beiden Systemen verwenden - ihre 1MB sind eigentlich 1024000 Bytes.

38voto

cocco Punkte 15866

Hier ist ein Prototyp zur Umwandlung einer Zahl in eine lesbare Zeichenkette, die den neuen internationalen Standards entspricht.

Es gibt zwei Möglichkeiten, große Zahlen darzustellen: Man kann sie entweder anzeigen in Vielfachen von 1000 = 10 3 (Basis 10) oder 1024 = 2 10 (Basis 2). Wenn man durch 1000 teilt, verwendet man wahrscheinlich die SI-Präfixnamen, wenn man durch 1024 dividiert, verwendet man wahrscheinlich die IEC-Präfixnamen. Das Problem beginnt mit der Division durch 1024. Viele Anwendungen verwenden die SI-Präfixe Namen und einige verwenden die IEC-Präfix-Namen. Die derzeitige Situation ist ein Durcheinander. Wenn Sie SI-Präfixnamen sehen, wissen Sie nicht, ob die Zahl durch 1000 oder 1024 geteilt wird

https://wiki.ubuntu.com/UnitsPolicy

http://en.wikipedia.org/wiki/Template:Quantities_of_bytes

Object.defineProperty(Number.prototype,'fileSize',{value:function(a,b,c,d){
 return (a=a?[1e3,'k','B']:[1024,'K','iB'],b=Math,c=b.log,
 d=c(this)/c(a[0])|0,this/b.pow(a[0],d)).toFixed(2)
 +' '+(d?(a[1]+'MGTPEZY')[--d]+a[2]:'Bytes');
},writable:false,enumerable:false});

Diese Funktion enthält keine loop und ist daher wahrscheinlich schneller als einige andere Funktionen.

Verwendung:

IEC-Präfix

console.log((186457865).fileSize()); // default IEC (power 1024)
//177.82 MiB
//KiB,MiB,GiB,TiB,PiB,EiB,ZiB,YiB

SI-Präfix

console.log((186457865).fileSize(1)); //1,true for SI (power 1000)
//186.46 MB 
//kB,MB,GB,TB,PB,EB,ZB,YB

Ich habe IEC als Standard eingestellt, weil ich immer den Binärmodus zur Berechnung der Dateigröße verwendet habe... mit der Potenz von 1024


Wenn Sie nur einen von ihnen in einer kurzen Oneliner-Funktion benötigen:

SI

function fileSizeSI(a,b,c,d,e){
 return (b=Math,c=b.log,d=1e3,e=c(a)/c(d)|0,a/b.pow(d,e)).toFixed(2)
 +' '+(e?'kMGTPEZY'[--e]+'B':'Bytes')
}
//kB,MB,GB,TB,PB,EB,ZB,YB

IEC

function fileSizeIEC(a,b,c,d,e){
 return (b=Math,c=b.log,d=1024,e=c(a)/c(d)|0,a/b.pow(d,e)).toFixed(2)
 +' '+(e?'KMGTPEZY'[--e]+'iB':'Bytes')
}
//KiB,MiB,GiB,TiB,PiB,EiB,ZiB,YiB

Verwendung:

console.log(fileSizeIEC(7412834521));

Wenn Sie Fragen zu den Funktionen haben, fragen Sie einfach

25voto

Joshaven Potter Punkte 10208
sizeOf = function (bytes) {
  if (bytes == 0) { return "0.00 B"; }
  var e = Math.floor(Math.log(bytes) / Math.log(1024));
  return (bytes/Math.pow(1024, e)).toFixed(2)+' '+' KMGTP'.charAt(e)+'B';
}

sizeOf(2054110009);
//=> "1,91 GB"

sizeOf(7054110);
//=> "6,73 MB"

sizeOf( (3*1024*1024) );
//=> "3,00 MB"

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X