【问题标题】:How to find the size of localStorage如何找到localStorage的大小
【发布时间】:2011-05-22 10:50:40
【问题描述】:

我目前正在开发一个使用 HTML5 的 localStorage 的网站。我已经阅读了所有关于不同浏览器的大小限制的信息。但是,我还没有看到任何关于如何找出 localStorage 实例的当前大小的信息。 This question 似乎表明 JavaScript 没有内置的方式来显示给定变量的大小。 localStorage 是否有我没见过的内存大小属性?有没有我想念的简单方法?

我的网站旨在允许用户以“离线”模式输入信息,因此能够在存储空间快满时向他们发出警告非常重要。

【问题讨论】:

标签: javascript html local-storage


【解决方案1】:

在 JavaScript 控制台中执行这个 sn-p(一行版本):

var _lsTotal=0,_xLen,_x;for(_x in localStorage){ if(!localStorage.hasOwnProperty(_x)){continue;} _xLen= ((localStorage[_x].length + _x.length)* 2);_lsTotal+=_xLen; console.log(_x.substr(0,50)+" = "+ (_xLen/1024).toFixed(2)+" KB")};console.log("Total = " + (_lsTotal / 1024).toFixed(2) + " KB");


为了阅读,多行相同的代码

var _lsTotal = 0,
    _xLen, _x;
for (_x in localStorage) {
    if (!localStorage.hasOwnProperty(_x)) {
        continue;
    }
    _xLen = ((localStorage[_x].length + _x.length) * 2);
    _lsTotal += _xLen;
    console.log(_x.substr(0, 50) + " = " + (_xLen / 1024).toFixed(2) + " KB")
};
console.log("Total = " + (_lsTotal / 1024).toFixed(2) + " KB");

或将此文本添加到书签的“位置”字段中以方便使用

javascript: var x, xLen, log=[],total=0;for (x in localStorage){if(!localStorage.hasOwnProperty(x)){continue;} xLen =  ((localStorage[x].length * 2 + x.length * 2)/1024); log.push(x.substr(0,30) + " = " +  xLen.toFixed(2) + " KB"); total+= xLen}; if (total > 1024){log.unshift("Total = " + (total/1024).toFixed(2)+ " MB");}else{log.unshift("Total = " + total.toFixed(2)+ " KB");}; alert(log.join("\n")); 

附:片段根据评论中的要求进行更新。现在计算包括密钥本身的长度。 每个长度都乘以 2,因为 javascript 中的 char 存储为 UTF-16(占用 2 个字节)

附言应该可以在 Chrome 和 Firefox 中使用。

【讨论】:

  • 粘贴到控制台查看总数:var t = 0; for(var x in localStorage){ t += (((localStorage[x].length * 2))); } console.log(t/1024+ "KB");
  • @Micah Javascript 在内部使用 UTF16,因此由于每个字符存储为两个字节,因此您需要将字符数乘以 2 以获得实际使用的空间。 (您可能已经发现了这一点,但我认为这里值得注意,只是因为其他人有同样的问题)
  • @Serge,这个答案投票最多,因此在这里发布var t = 0; for(var x in localStorage) { t += (x.length + localStorage[x].length) * 2; } console.log(t/1024+ " KB");
  • 这是一个修改后的版本,它也考虑了 NaN:var _lsTotal = 0, _xLen, _x; for (_x in localStorage) { _xLen = (((localStorage[_x].length || 0) + (_x.length || 0)) * 2); _lsTotal += _xLen; console.log(_x.substr(0, 50) + " = " + (_xLen / 1024).toFixed(2) + " KB") }; console.log("Total = " + (_lsTotal / 1024).toFixed(2) + " KB");
  • 书签中有一个错误。您在主代码中使用带下划线的变量,在书签中使用普通名称。单下划线_x 打破它。只需删除下划线即可。
【解决方案2】:

离开上面@Shourav 所说的内容,我编写了一个小函数,它应该准确地获取您所有的localStorage 键(对于当前域)并计算组合大小,以便您确切知道占用了多少内存通过您的localStorage 对象:

var localStorageSpace = function(){
        var allStrings = '';
        for(var key in window.localStorage){
            if(window.localStorage.hasOwnProperty(key)){
                allStrings += window.localStorage[key];
            }
        }
        return allStrings ? 3 + ((allStrings.length*16)/(8*1024)) + ' KB' : 'Empty (0 KB)';
    };

我的返回:"30.896484375 KB"

【讨论】:

  • 谢谢@tennisgent。我的适用于 IE11,FF > 26 和 Chrome。
【解决方案3】:

您可以使用Blob function.获取本地存储数据的当前大小,这可能不适用于旧浏览器,请在caniuse查看对new BlobObject.values()的支持。

例子:

return new Blob(Object.values(localStorage)).size;

Object.values() 将 localStorage 对象转换为数组。 Blob 将数组转换为原始数据。

【讨论】:

  • 我认为Blob 不会将字符串编码限制为UTF-16,因此这实际上可能是最可靠的方法。 new Blob(['X']).size; = 1 而new Blob(['☃']).size (U+2603 / 雪人字符) ==> 3. 基于String.prototype.length 的解决方案不考虑这一点(处理“字符”),而存储配额/限制可能会考虑(处理字节),我可以想象这会导致意外,例如,在存储非英语/ASCII 字符时。
  • 我使用 Jed 的答案计算 localStorage 大小和字符串长度来测试 Chrome 和 FF 中的 Blob 解决方案。在第一次测试中,我用符号“1”填充了 localStorage。在第二次测试中,我用符号 ''☃'' 填充 localStorage,它在 Blob 对象中具有更大的大小。在这两种情况下,我得到的最大 localStorage 长度完全相同。所以 Blob 字符大小不会影响 localStorage 限制。这就是为什么不应该将 Blob 用于此目的的原因。
  • 我得到 195... 195 什么?
  • Blob 将包含一个文本。 UTF-8 文本。而localStorage 将值存储为 UTF-16。因此,它将打印大约 2 倍的值。
【解决方案4】:

IE 具有存储对象的remainingSpace 属性。其他浏览器目前没有等价物。

我相信默认的空间大小是 5MB,虽然我没有亲自测试过。

【讨论】:

  • 这是一个仅限 IE 的属性
  • 是每个站点的 5 mb 限制还是所有站点的总体限制?
  • @divyenduz 每个站点,我认为
  • 请注意,localStorage.remainingSpace 属性返回存储对象允许的剩余 UTF-16 字符数。不是以字节为单位的剩余大小。 Reference
【解决方案5】:

希望这对某人有所帮助。

因为 jsfiddle 上的 Jas- 示例对我不起作用,所以我想出了这个解决方案。 (感谢 Serge Seletskyy 和 Shourav 我在下面的代码中使用的位)

下面是可以用来测试有多少空间可用于localStorage 以及(如果任何键已经在lS 中)还剩下多少空间的函数。

这是一种蛮力,但它几乎适用于所有浏览器……除了 Firefox。 好吧,在桌面 FF 中需要很长时间(4-5 分钟)才能完成,而在 Android 上它只会崩溃。

函数下面是我在不同平台的不同浏览器中所做的测试的简短摘要。享受吧!

function testLocalStorage() {
    var timeStart = Date.now();
    var timeEnd, countKey, countValue, amountLeft, itemLength;
    var occupied = leftCount = 3; //Shurav's comment on initial overhead
//create localStorage entries until localStorage is totally filled and browser issues a warning.
    var i = 0;
    while (!error) {
        try {
//length of the 'value' was picked to be a compromise between speed and accuracy, 
// the longer the 'value' the quicker script and result less accurate. This one is around 2Kb 
            localStorage.setItem('testKey' + i, '11111111112222222222333333333344444444445555555555666661111111111222222222233333333334444444444555555555566666');
        } catch (e) {
            var error = e;
        }
        i++;
    }
//if the warning was issued - localStorage is full.
    if (error) {
//iterate through all keys and values to count their length
        for (var i = 0; i < localStorage.length; i++) {
            countKey = localStorage.key(i);
            countValue = localStorage.getItem(localStorage.key(i));
            itemLength = countKey.length + countValue.length;
//if the key is one of our 'test' keys count it separately
            if (countKey.indexOf("testKey") !== -1) {
                leftCount = leftCount + itemLength;
            }
//count all keys and their values
            occupied = occupied + itemLength;
        }
        ;
//all keys + values lenght recalculated to Mb
        occupied = (((occupied * 16) / (8 * 1024)) / 1024).toFixed(2);
//if there are any other keys then our 'testKeys' it will show how much localStorage is left
        amountLeft = occupied - (((leftCount * 16) / (8 * 1024)) / 1024).toFixed(2);
//iterate through all localStorage keys and remove 'testKeys'
        Object.keys(localStorage).forEach(function(key) {
            if (key.indexOf("testKey") !== -1) {
                localStorage.removeItem(key);
            }
        });

    }
//calculate execution time
    var timeEnd = Date.now();
    var time = timeEnd - timeStart;
//create message
    var message = 'Finished in: ' + time + 'ms \n total localStorage: ' + occupied + 'Mb \n localStorage left: ' + amountLeft + "Mb";
//put the message on the screen
    document.getElementById('scene').innerText = message; //this works with Chrome,Safari, Opera, IE
//document.getElementById('scene').textContent = message;  //Required for Firefox to show messages
}

正如上面所承诺的,在不同的浏览器中进行了一些测试:

GalaxyTab 10.1

  • Maxthon Pad 1.7 ~1130ms 5Mb
  • Firefox 20.0(Beta 20.0)同时崩溃
  • 铬 25.0.1364.169 ~22250ms /5Mb
  • 本机(标识为 Safari 4.0/Webkit534.30)~995ms /5Mb

iPhone 4s iOS 6.1.3

  • Safari ~ 520ms /5Mb
  • 作为 HomeApp ~525ms / 5Mb
  • iCab ~ 710ms /5mb

MacBook Pro OSX 1.8.3(Core 2 Duo 2.66 8Gb 内存)

  • Safari 6.0.3 ~105ms /5Mb
  • Chrome 26.0.1410.43 ~3400ms /5Mb
  • Firefox 20.0 300150ms(!) /10Mb(在抱怨脚本运行时间过长之后)

iPad 3 iOS 6.1.3

  • Safari ~430ms /5Mb
  • iCab ~595ms /5mb

Windows 7 -64b(Core 2 Duo 2.93 6Gb 内存)

  • Safari 5.1.7 ~80ms /5Mb
  • Chrome 26.0.1410.43 ~1220ms /5Mb
  • Firefox 20.0 228500ms(!) /10Mb(在抱怨脚本运行时间过长之后)
  • IE9 ~17900ms /9.54Mb(如果代码中有任何 console.logs 在 DevTools 打开之前无法工作)
  • Opera 12.15 ~4212ms /3.55Mb(这是选择 5Mb 时,但 Opera 会很好地询问我们是否要增加 lS 的量,不幸的是,如果连续进行几次测试它会崩溃)

Win 8(在 Parallels 8 下)

  • IE10 ~7850ms /9.54Mb

【讨论】:

  • 伟大的实验。但是我在你的代码中找到了array.forEach(),因为我知道它在IE中不存在,你自己实现吗?您如何衡量它对整体延迟的贡献?
  • 谢谢,我可能会重做它们,因为从最初的测试过去了一段时间。至于forEach()。不,我自己没有实现它,我使用了股票Array.prototype.forEach()。根据来自 IE9 的Mozilla Developer Network aka MDN,它具有原生支持。
  • 谢谢。我的知识需要更新。以后如果我的项目不支持早期的IE版本,我会尽量使用Array.prototype.forEach()
  • 代码可以显着加快(在 Firefox 中约为 2500 毫秒,在 Chrome 中约为 700 毫秒):将 while 循环分成两部分,第一部分类似于 stackoverflow.com/a/3027249/1235394用指数增长的数据块填充 localStorage,然后用固定大小的小块填充第二部分以完全填充存储。测试页面:jsfiddle.net/pqpps3tk/1
  • IE10 Rocks.. 仍然是下载 Chrome 的最快浏览器 :)
【解决方案6】:

这是一个简单的example 说明如何做到这一点,并且应该适用于所有浏览器

alert(1024 * 1024 * 5 - unescape(encodeURIComponent(JSON.stringify(localStorage))).length);

【讨论】:

  • 你不需要*8吗?
  • 取决于不考虑的字符集(即 utf8 等)
  • 这是以字节为单位还是以位为单位给出大小?
  • 此示例错误地假设 localStorage 在每个浏览器中具有相同的固定限制,即 5MB (5 * 1024 * 1024)。
  • 这是根据 w3c 提出的规范。
【解决方案7】:

您可以通过以下方法计算您的本地存储:

function sizeofAllStorage(){  // provide the size in bytes of the data currently stored
  var size = 0;
  for (i=0; i<=localStorage.length-1; i++)  
  {  
  key = localStorage.key(i);  
  size += lengthInUtf8Bytes(localStorage.getItem(key));
  }  
  return size;
}

function lengthInUtf8Bytes(str) {
  // Matches only the 10.. bytes that are non-initial characters in a multi-byte sequence.
  var m = encodeURIComponent(str).match(/%[89ABab]/g);
  return str.length + (m ? m.length : 0);
}

console.log(sizeofAllStorage());

最终以字节为单位的大小将记录在浏览器中。

【讨论】:

    【解决方案8】:

    我会使用@tennisgen 的代码获取所有内容并计算内容,但我自己计算密钥:

    var localStorageSpace = function(){
            var allStrings = '';
            for(var key in window.localStorage){
                allStrings += key;
                if(window.localStorage.hasOwnProperty(key)){
                    allStrings += window.localStorage[key];
                }
            }
            return allStrings ? 3 + ((allStrings.length*16)/(8*1024)) + ' KB' : 'Empty (0 KB)';
        };
    

    【讨论】:

      【解决方案9】:

      我解决这个问题的方法是创建函数来找出本地存储中的已用空间和剩余空间,然后创建一个函数来调用这些函数以确定最大存储空间。

      function getUsedSpaceOfLocalStorageInBytes() {
          // Returns the total number of used space (in Bytes) of the Local Storage
          var b = 0;
          for (var key in window.localStorage) {
              if (window.localStorage.hasOwnProperty(key)) {
                  b += key.length + localStorage.getItem(key).length;
              }
          }
          return b;
      }
      
      function getUnusedSpaceOfLocalStorageInBytes() {
          var maxByteSize = 10485760; // 10MB
          var minByteSize = 0;
          var tryByteSize = 0;
          var testQuotaKey = 'testQuota';
          var timeout = 20000;
          var startTime = new Date().getTime();
          var unusedSpace = 0;
          do {
              runtime = new Date().getTime() - startTime;
              try {
                  tryByteSize = Math.floor((maxByteSize + minByteSize) / 2);
                  localStorage.setItem(testQuotaKey, new Array(tryByteSize).join('1'));
                  minByteSize = tryByteSize;
              } catch (e) {
                  maxByteSize = tryByteSize - 1;
              }
          } while ((maxByteSize - minByteSize > 1) && runtime < timeout);
      
          localStorage.removeItem(testQuotaKey);
      
          if (runtime >= timeout) {
              console.log("Unused space calculation may be off due to timeout.");
          }
      
          // Compensate for the byte size of the key that was used, then subtract 1 byte because the last value of the tryByteSize threw the exception
          unusedSpace = tryByteSize + testQuotaKey.length - 1;
          return unusedSpace;
      }
      
      function getLocalStorageQuotaInBytes() {
          // Returns the total Bytes of Local Storage Space that the browser supports
          var unused = getUnusedSpaceOfLocalStorageInBytes();
          var used = getUsedSpaceOfLocalStorageInBytes();
          var quota = unused + used;
          return quota;
      }
      

      【讨论】:

      • Array.join 是性能杀手,最好在可用的地方使用 String.repeat(这意味着除了 IE 之外的任何地方)
      【解决方案10】:

      除了@serge 在这里投票最多的答案之外,还需要考虑密钥的大小。下面的代码将添加存储在localStorage中的键的大小

      var t = 0; 
      for (var x in localStorage) { 
          t += (x.length + localStorage[x].length) * 2; 
      } 
      console.log((t / 1024) + " KB");
      

      【讨论】:

      • 我发现 Firefox 在某些情况下会为 length 项返回 undefined,因此我在添加中添加了一个条件:t += (x.length + (this.storage[x].length ? this.storage[x].length : 0)) * 2;
      • @camilokawerin,除非在存储中保存未定义的值,否则不应该这样做,因为 String 是 localStorage 支持的唯一类型,并且 String 确实具有属性 Length。你能在 jsfiddle 或类似的东西上发布一些例子吗?
      【解决方案11】:

      按照规范,字符串的每个字符都是 16 位的。

      但是使用 chrome(设置>内容设置>Cookie 和站点数据)检查显示,启动 localStorage 需要 3kB(开销大小)

      并且存储的数据大小遵循这个关系(精确到1kB)
      3 + ((localStorage.x.length*16)/(8*1024)) kB

      localStorage.x 是您的存储字符串。

      【讨论】:

        【解决方案12】:

        是的,这个问题就像 10 年前一样被问到。但是对于那些有兴趣(比如我自己,因为我正在构建一个使用本地存储保存数据的离线文本编辑器)并且不擅长编程的人,您可以使用如下简单的东西:

        var warning = 1;
        var limit = 2000000; //2 million characters, not really taking in account to bytes but for tested number of characters stored
        setInterval(function() {
            localStorage["text"] = document.getElementById("editor").innerHTML; //gets text and saves it in local storage under "text"
            if(localStorage["text"].length > limit && warning == 1){
                    alert("Local Storage capacity has been filled"); 
                    warning = 2; //prevent a stream of alerts
            }
        }, 1000);
        //setInterval function saves and checks local storage
        

        获取已填满存储量的最佳方法是查看站点设置(例如,如果您将图像存储在本地存储中)。至少在 chrome 中,您可以看到使用的字节数(即:1222 字节)。但是,上面已经提到了使用 js 查看填充本地存储的最佳方法,因此请使用它们。

        【讨论】:

          【解决方案13】:

          //key和value都占用内存所以更新代码。

          var jsonarr=[];
          var jobj=null;
          for(x in sessionStorage) // Iterate through each session key
          {
              jobj={}; 
              jobj[x]=sessionStorage.getItem(x); //because key will also occupy some memory
              jsonarr.push(jobj);
              jobj=null;
          }
          //https://developer.mozilla.org/en/docs/Web/JavaScript/Data_structures 
          //JavaScript's String type is used to represent textual data. It is a set of "elements" of 16-bit unsigned integer values. 
          var size=JSON.stringify(jsonarr).length*2; //16-bit that's why multiply by 2
          var arr=["bytes","KB","MB","GB","TB"]; // Define Units
          var sizeUnit=0;
          while(size>1024){ // To get result in Proper Unit
              sizeUnit++;
              size/=1024;
          }
          alert(size.toFixed(2)+" "+arr[sizeUnit]);
          

          【讨论】:

            【解决方案14】:
            window.localStorage.remainingSpace
            

            【讨论】:

            • 如上所述 - 这是一个仅限 IE 的属性。
            猜你喜欢
            • 2011-08-14
            • 1970-01-01
            • 2012-07-28
            • 2017-08-12
            • 2015-10-02
            • 1970-01-01
            • 2018-09-30
            • 2011-11-24
            相关资源
            最近更新 更多