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

l2a*_*lba 216 javascript byte converters

我得到这个代码通过PHP来隐藏大小的字节数.

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

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;
}
Run Code Online (Sandbox Code Playgroud)

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

Ali*_*ljm 653

由此:( 来源)

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];
}
Run Code Online (Sandbox Code Playgroud)

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


现在,修正版:( 通过Stackoverflow的社区,+由JSCompress缩小)

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];
}
Run Code Online (Sandbox Code Playgroud)

用法:

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]}
Run Code Online (Sandbox Code Playgroud)

演示/来源:

// formatBytes(bytes,decimals)

formatBytes(1024);       // 1 KB
formatBytes('1024');     // 1 KB
formatBytes(1234);       // 1.21 KB
formatBytes(1234, 3);    // 1.205 KB
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)

PS:更改k = 1000sizes = ["..."]根据需要(字节)

  • 我认为minify很好,但在stackexchange中,最好有更详细和可读的代码. (12认同)
  • (1)为什么bytes = 0是"n/a"?是不是只是"0 B"?(2)Math.round没有精度参数.我最好用`(bytes/Math.pow(1024,i)).toPrecision(3)` (8认同)
  • `toFixed(n)`可能比`toPrecision(n)`更适合所有值的一致精度.并且为了避免尾随零(例如:`bytesToSize(1000)//返回"1.00 KB"`),我们可以使用`parseFloat(x)`.我建议用以下代码替换最后一行:`return parseFloat((bytes/Math.pow(k,i)).toFixed(2))+''+ sizes [i];`.对于先前的更改,结果是:`bytesToSize(1000)//返回"1 KB"`/`bytesToSize(1100)//返回"1.1 KB"`/`bytesToSize(1110)//返回"1.11 KB` /` bytesToSize(1111)//也返回"1.11 KB" (4认同)
  • 我相信复数形式用于0:'0字节' (3认同)
  • KB = SI单位的开尔文字节。这是荒谬的。应该是kB。 (2认同)
  • 我认为我们不应该在帮助主题中显示“最小化和压缩”版本。我建议我们将其最小化/解压缩。我将此添加到主题中。 (2认同)
  • 准确地说,如果“k”是 1024,那么单位缩写应该是“KiB”、“MiB”、“GiB”等。这些是[kibibytes、mebibytes、gibibytes](https://physicals.nist.gov/ cuu/Units/binary.html) 等 (2认同)
  • 这是不对的,1 kb 是 1000 字节,而不是 1024。所以 K 应该是 1000 (2认同)

Jay*_*ram 43

function formatBytes(bytes) {
    var marker = 1024; // Change to 1000 if required
    var decimal = 3; // Change as required
    var kiloBytes = marker; // One Kilobyte is 1024 bytes
    var megaBytes = marker * marker; // One MB is 1024 KB
    var gigaBytes = marker * marker * marker; // One GB is 1024 MB
    var teraBytes = marker * marker * marker * marker; // One TB is 1024 GB

    // return bytes if less than a KB
    if(bytes < kiloBytes) return bytes + " Bytes";
    // return KB if less than a MB
    else if(bytes < megaBytes) return(bytes / kiloBytes).toFixed(decimal) + " KB";
    // return MB if less than a GB
    else if(bytes < gigaBytes) return(bytes / megaBytes).toFixed(decimal) + " MB";
    // return GB if less than a TB
    else return(bytes / gigaBytes).toFixed(decimal) + " GB";
}
Run Code Online (Sandbox Code Playgroud)


Fau*_*ust 24

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

function niceBytes(x){
  if(x === 1) return '1 byte';

  let l = 0, n = parseInt(x, 10) || 0;

  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]);
}
Run Code Online (Sandbox Code Playgroud)

结果:

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
Run Code Online (Sandbox Code Playgroud)

  • *谢谢!* **压缩:** `函数niceBytes(a){let b=0,c=parseInt(a,10)||0;for(;1024&lt;=c&amp;&amp;++b;)c/=1024 ;return c.toFixed(10&gt;c&amp;&amp;0&lt;b?1:0)+" "+["字节","KB","MB","GB","TB","PB","EB"," ZB","YB"][b]}` (4认同)

mau*_*chi 14

您可以使用filesizejs库.

  • @WM那句话不对.1kB = 1000字节.Kibibyte中有1024个字节.过去一直存在混淆,因此这两个术语正好解释了规模的差异. (3认同)
  • @BrennanT这取决于你多大了.1KB过去是1024字节,大多数人在一定年龄仍然看到它. (2认同)
  • 对于来这里寻求库的人来说,这里是更好的一个:https://www.npmjs.com/package/pretty-bytes (2认同)

Bre*_*n T 12

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

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

请享用.

// 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];
    }
}
Run Code Online (Sandbox Code Playgroud)


iDa*_*N5x 12

这是一个班轮:

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

甚至:

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

  • 这很好!我对此进行了扩展,以从函数中返回我想要的完整字符串:`i = ~~(Math.log2(b)/10); return (b/Math.pow(1024,i)).toFixed(2) + ("KMGTPEZY"[i-1]||"") + "B"` (3认同)
  • 该计算*是将1k视为2 ^ 10,1m为2 ^ 20,依此类推.如果你希望1k为1000,你可以稍微改一下使用log10. (2认同)
  • 这是将 1K 视为 1000 的版本: `val =&gt; 'BKMGT'[~~(Math.log10(val)/3)]` (2认同)

Mat*_*jra 8

将字节格式化为最逻辑大小(KB、MB 或 GB)的实用方法

Number.prototype.formatBytes = function() {
    var units = ['B', 'KB', 'MB', 'GB', 'TB'],
        bytes = this,
        i;
 
    for (i = 0; bytes >= 1024 && i < 4; i++) {
        bytes /= 1024;
    }
 
    return bytes.toFixed(2) + units[i];
}

let a = 235678; //bytes

console.log(a.formatBytes()); //result is 230.15KB
Run Code Online (Sandbox Code Playgroud)


med*_*zid 8

只需稍微修改 @zayarTun 答案的代码,以包含一个表示结果中小数位数的额外参数(另外,如果小数为零,则无需显示 15.00 KB 之类的结果,而是 15 KB 就足够了,这就是我包装的原因中的结果值parseFloat()

  bytesForHuman(bytes, decimals = 2) {
    let units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']

    let i = 0
    
    for (i; bytes > 1024; i++) {
        bytes /= 1024;
    }

    return parseFloat(bytes.toFixed(decimals)) + ' ' + units[i]
  }
Run Code Online (Sandbox Code Playgroud)


小智 6

这对我有用。

bytesForHuman(bytes) {
    let units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']

    let i = 0
    
    for (i; bytes > 1024; i++) {
        bytes /= 1024;
    }

    return bytes.toFixed(1) + ' ' + units[i]
}
Run Code Online (Sandbox Code Playgroud)


Buz*_*ear 5

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

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 ;
}
Run Code Online (Sandbox Code Playgroud)

  • 亲爱的Amir Haghighat,这是我自己编写的基本代码.在javasript发布32位整数值后,代码将无法工作,因为整数只有4个字节.这些是你应该知道的基本编程信息.Stackoverflow仅用于引导人而不是勺子喂食. (8认同)
  • 请不要在没有理解或至少测试它的情况下从互联网上获取代码。这是一个完全错误的代码的好例子。尝试通过传递 3(返回“1Bytes”)或 400000 来运行它。 (3认同)
  • 它是 1024。如果您需要 100,则相应地移动这些位。 (2认同)
  • [链接](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators) (2认同)