在JavaScript中将大小(以字节为单位)转换为KB,MB,GB的正确方法

问题描述 投票:188回答:14

我得到qazxsw poi通过PHP转换大小的字节数。

现在我想使用JavaScript将这些大小转换为人类可读的大小。我试图将此代码转换为JavaScript,如下所示:

this code

这是正确的做法吗?有没有更简单的方法?

javascript byte converters
14个回答
587
投票

由此:(function formatSizeUnits(bytes){ if (bytes >= 1073741824) { bytes = (bytes / 1073741824).toFixed(2) + " GB"; } else if (bytes >= 1048576) { bytes = (bytes / 1048576).toFixed(2) + " MB"; } else if (bytes >= 1024) { bytes = (bytes / 1024).toFixed(2) + " KB"; } else if (bytes > 1) { bytes = bytes + " bytes"; } else if (bytes == 1) { bytes = bytes + " byte"; } else { bytes = "0 bytes"; } return bytes; }

source

注意:这是原始代码,请使用下面的固定版本。 Aliceljm不再激活她复制的代码


现在,未修改的固定版本和ES6':(按社区)

function bytesToSize(bytes) {
   var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
   if (bytes == 0) return '0 Byte';
   var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
   return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
};

现在,修正版:(通过Stackoverflow的社区,+由function formatBytes(bytes, decimals = 2) { if (bytes === 0) return '0 Bytes'; const k = 1024; const dm = decimals < 0 ? 0 : decimals; const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; } 缩小)

JSCompress

用法:

function formatBytes(a,b){if(0==a)return"0 Bytes";var c=1024,d=b||2,e=["Bytes","KB","MB","GB","TB","PB","EB","ZB","YB"],f=Math.floor(Math.log(a)/Math.log(c));return parseFloat((a/Math.pow(c,f)).toFixed(d))+" "+e[f]}

演示/来源:

// formatBytes(bytes,decimals)

formatBytes(1024);       // 1 KB
formatBytes('1024');     // 1 KB
formatBytes(1234);       // 1.21 KB
formatBytes(1234, 3);    // 1.205 KB
function formatBytes(bytes,decimals) {
   if(bytes == 0) return '0 Bytes';
   var k = 1024,
       dm = decimals <= 0 ? 0 : decimals || 2,
       sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
       i = Math.floor(Math.log(bytes) / Math.log(k));
   return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}


// ** Demo code **
var p = document.querySelector('p'),
    input = document.querySelector('input');
    
function setText(v){
    p.innerHTML = formatBytes(v);
}
// bind 'input' event
input.addEventListener('input', function(){ 
    setText( this.value )
})
// set initial text
setText(input.value);

PS:根据需要更改<input type="text" value="1000"> <p></p>k = 1000(位或字节)


2
投票

24.8mb

1
投票

我在这里更新@Aliceljm答案。由于小数位对1,2位数字很重要,因此我将小数点后第一位并保留第一个小数位。对于3位数字,我舍入单位位置并忽略所有小数位。

function bytesToSize(bytes) {
  var sizes = ['B', 'K', 'M', 'G', 'T', 'P'];
  for (var i = 0; i < sizes.length; i++) {
    if (bytes <= 1024) {
      return bytes + ' ' + sizes[i];
    } else {
      bytes = parseFloat(bytes / 1024).toFixed(2)
    }
  }
  return bytes + ' P';
}

console.log(bytesToSize(234));
console.log(bytesToSize(2043));
console.log(bytesToSize(20433242));
console.log(bytesToSize(2043324243));
console.log(bytesToSize(2043324268233));
console.log(bytesToSize(2043324268233343));

1
投票

此解决方案基于以前的解决方案,但考虑了公制和二进制单位:

getMultiplers : function(bytes){
    var unit = 1000 ;
    if (bytes < unit) return bytes ;
    var exp = Math.floor(Math.log(bytes) / Math.log(unit));
    var pre = "kMGTPE".charAt(exp-1);
    var result = bytes / Math.pow(unit, exp);
    if(result/100 < 1)
        return (Math.round( result * 10 ) / 10) +pre;
    else
        return Math.round(result) + pre;
}

例子:

function formatBytes(bytes, decimals, binaryUnits) {
    if(bytes == 0) {
        return '0 Bytes';
    }
    var unitMultiple = (binaryUnits) ? 1024 : 1000; 
    var unitNames = (unitMultiple === 1024) ? // 1000 bytes in 1 Kilobyte (KB) or 1024 bytes for the binary version (KiB)
        ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']: 
        ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
    var unitChanges = Math.floor(Math.log(bytes) / Math.log(unitMultiple));
    return parseFloat((bytes / Math.pow(unitMultiple, unitChanges)).toFixed(decimals || 0)) + ' ' + unitNames[unitChanges];
}

0
投票

formatBytes(293489203947847, 1);    // 293.5 TB
formatBytes(1234, 0);   // 1 KB
formatBytes(4534634523453678343456, 2); // 4.53 ZB
formatBytes(4534634523453678343456, 2, true));  // 3.84 ZiB
formatBytes(4566744, 1);    // 4.6 MB
formatBytes(534, 0);    // 534 Bytes
formatBytes(273403407, 0);  // 273 MB

-4
投票

试试这个简单的解决方法。

var SIZES = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];

function formatBytes(bytes, decimals) {
  for(var i = 0, r = bytes, b = 1024; r > b; i++) r /= b;
  return `${parseFloat(r.toFixed(decimals))} ${SIZES[i]}`;
}

40
投票
sizes = ["..."]

22
投票
function formatBytes(bytes) {
    if(bytes < 1024) return bytes + " Bytes";
    else if(bytes < 1048576) return(bytes / 1024).toFixed(3) + " KB";
    else if(bytes < 1073741824) return(bytes / 1048576).toFixed(3) + " MB";
    else return(bytes / 1073741824).toFixed(3) + " GB";
};

结果:

const units = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];

function niceBytes(x){
  let l = 0, n = parseInt(x, 10) || 0;
  if(n === 1) return '1 byte'

  while(n >= 1024 && ++l){
      n = n/1024;
  }
  //include a decimal point and a tenths-place digit if presenting 
  //less than ten of KB or greater units
  return(n.toFixed(n < 10 && l > 0 ? 1 : 0) + ' ' + units[l]);
}

12
投票

当与字节相关时,有两种实际方式来表示大小,它们是SI单位(10 ^ 3)或IEC单位(2 ^ 10)。还有JEDEC,但他们的方法含糊不清,令人困惑。我注意到其他示例有错误,例如使用KB而不是kB来表示千字节,因此我决定编写一个函数,使用当前接受的度量单位范围来解决每个案例。

最后有一个格式化位会使数字看起来更好(至少在我看来)如果它不适合你的目的,可以随意删除该格式。

请享用。

niceBytes(1)                   // 1 byte
niceBytes(435)                 // 435 bytes
niceBytes(3398)                // 3.3 KB
niceBytes(490398)              // 479 KB
niceBytes(6544528)             // 6.2 MB
niceBytes(23483023)            // 22 MB
niceBytes(3984578493)          // 3.7 GB
niceBytes(30498505889)         // 28 GB
niceBytes(9485039485039445)    // 8.4 PB

12
投票

您可以使用// pBytes: the size in bytes to be converted. // pUnits: 'si'|'iec' si units means the order of magnitude is 10^3, iec uses 2^10 function prettyNumber(pBytes, pUnits) { // Handle some special cases if(pBytes == 0) return '0 Bytes'; if(pBytes == 1) return '1 Byte'; if(pBytes == -1) return '-1 Byte'; var bytes = Math.abs(pBytes) if(pUnits && pUnits.toLowerCase() && pUnits.toLowerCase() == 'si') { // SI units use the Metric representation based on 10^3 as a order of magnitude var orderOfMagnitude = Math.pow(10, 3); var abbreviations = ['Bytes', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; } else { // IEC units use 2^10 as an order of magnitude var orderOfMagnitude = Math.pow(2, 10); var abbreviations = ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; } var i = Math.floor(Math.log(bytes) / Math.log(orderOfMagnitude)); var result = (bytes / Math.pow(orderOfMagnitude, i)); // This will get the sign right if(pBytes < 0) { result *= -1; } // This bit here is purely for show. it drops the percision on numbers greater than 100 before the units. // it also always shows the full number of bytes if bytes is the unit. if(result >= 99.995 || i==0) { return result.toFixed(0) + ' ' + abbreviations[i]; } else { return result.toFixed(2) + ' ' + abbreviations[i]; } } 库。


11
投票

这是一个班轮:

filesizejs

甚至:

val => ['Bytes','Kb','Mb','Gb','Tb'][Math.floor(Math.log2(val)/10)]


5
投票

使用按位运算将是更好的解决方案。试试这个

val => 'BKMGT'[~~(Math.log2(val)/10)]

4
投票

根据function formatSizeUnits(bytes) { if ( ( bytes >> 30 ) & 0x3FF ) bytes = ( bytes >>> 30 ) + '.' + ( bytes & (3*0x3FF )) + 'GB' ; else if ( ( bytes >> 20 ) & 0x3FF ) bytes = ( bytes >>> 20 ) + '.' + ( bytes & (2*0x3FF ) ) + 'MB' ; else if ( ( bytes >> 10 ) & 0x3FF ) bytes = ( bytes >>> 10 ) + '.' + ( bytes & (0x3FF ) ) + 'KB' ; else if ( ( bytes >> 1 ) & 0x3FF ) bytes = ( bytes >>> 1 ) + 'Bytes' ; else bytes = bytes + 'Byte' ; return bytes ; } 的回答,我在小数后删除了0:

Aliceljm

2
投票

我最初使用function formatBytes(bytes, decimals) { if(bytes== 0) { return "0 Byte"; } var k = 1024; //Or 1 kilo = 1000 var sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB"]; var i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + " " + sizes[i]; } 的答案来处理我正在处理的文件上传项目,但最近遇到了一个问题,其中一个文件是@Aliceljm但被读作0.98kb。这是我正在使用的更新代码。

1.02mb

然后在添加文件之后调用上面的内容

function formatBytes(bytes){
  var kb = 1024;
  var ndx = Math.floor( Math.log(bytes) / Math.log(kb) );
  var fileSizeTypes = ["bytes", "kb", "mb", "gb", "tb", "pb", "eb", "zb", "yb"];

  return {
    size: +(bytes / kb / kb).toFixed(2),
    type: fileSizeTypes[ndx]
  };
}

当然,Windows将文件读取为// In this case `file.size` equals `26060275` formatBytes(file.size); // returns `{ size: 24.85, type: "mb" }` ,但我的精确度更高。

© www.soinside.com 2019 - 2024. All rights reserved.