Javascript 如何查找本地存储的大小

Javascript 如何查找本地存储的大小,javascript,html,local-storage,Javascript,Html,Local Storage,我目前正在开发一个利用HTML5本地存储的网站。我已经阅读了关于不同浏览器的大小限制的所有内容。但是,我还没有看到任何关于如何找出localStorage实例的当前大小的内容。似乎表明JavaScript没有显示给定变量大小的内置方式。localStorage是否有我从未见过的内存大小属性?有没有一个简单的方法可以做到这一点,我错过了 我的网站旨在允许用户以“脱机”模式输入信息,因此在存储空间几乎满时向他们发出警告非常重要 IE具有存储对象的属性。其他浏览器此时没有对应的浏览器 window.l

我目前正在开发一个利用HTML5本地存储的网站。我已经阅读了关于不同浏览器的大小限制的所有内容。但是,我还没有看到任何关于如何找出localStorage实例的当前大小的内容。似乎表明JavaScript没有显示给定变量大小的内置方式。localStorage是否有我从未见过的内存大小属性?有没有一个简单的方法可以做到这一点,我错过了

我的网站旨在允许用户以“脱机”模式输入信息,因此在存储空间几乎满时向他们发出警告非常重要

IE具有存储对象的属性。其他浏览器此时没有对应的浏览器

window.localStorage.remainingSpace
我相信默认的空间量是5MB,尽管我还没有亲自测试过它。

这里简单介绍了如何做到这一点,应该适用于每个浏览器

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

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

但通过chrome(设置>内容设置>Cookies和站点数据)检查,我们发现启动本地存储需要3kB(开销大小)

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


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

在JavaScript控制台中执行此代码段(单行版本):

为了便于阅读,在多行中使用相同的代码

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中的字符存储为UTF-16(占用2个字节)


p.p.S.应该在Chrome和Firefox中都能使用。

希望这对其他人有所帮助

因为JSFIDLE上的Jas-example不适合我,所以我提出了这个解决方案。 (感谢Serge Seletskyy和Shourav在下面的代码中使用了他们的位)

下面是一个函数,可用于测试本地存储的可用空间和剩余空间(如果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
}
函数testLocalStorage(){
var timeStart=Date.now();
var timeEnd、countKey、countValue、amountLeft、itemLength;
var accumped=leftCount=3;//Shurav对初始开销的评论
//创建localStorage条目,直到localStorage完全填满并且浏览器发出警告为止。
var i=0;
而(!错误){
试一试{
//选择“值”的长度是速度和准确性之间的折衷,
//“值”越长,脚本速度越快,结果越不准确。这个值大约为2Kb
setItem('testKey'+i',1111111111222222223333333 44444444 55555555 66666 1111111222222223333333 44444444 5555555555666');
}捕获(e){
var误差=e;
}
i++;
}
//如果发出警告-localStorage已满。
如果(错误){
//遍历所有键和值以计算其长度
for(var i=0;i
如上所述,在不同浏览器中进行一些测试:

GalaxyTab 10.1

  • Maxthon焊盘1.7~1130ms 5Mb
  • Firefox 20.0(Beta 20.0)同时崩溃
  • 铬25.0.1364.169~22200ms/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(核心2 Duo 2.66 8Gb内存)

  • Safari 6.0.3~105ms/5Mb
  • 铬26.0.1410.43~3400ms/5Mb
  • Firefox 20.0 300150ms(!)/10Mb(抱怨脚本运行太长)
iPad3 iOS 6.1.3

  • Safari~430ms/5Mb
  • iCab~595ms/5mb
Windows 7-64b(核心2 Duo 2.93 6Gb内存)

  • Safari 5.1.7~80ms/5Mb
  • 铬26.0.1410.43~1220ms/5Mb
  • Firefox 20.0 228500ms(!)/10Mb(抱怨脚本运行太长)
  • IE9~17900ms
    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
    }
    
    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)';
        };
    
    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());
    
    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)';
        };
    
    var t = 0; 
    for (var x in localStorage) { 
        t += (x.length + localStorage[x].length) * 2; 
    } 
    console.log((t / 1024) + " KB");
    
    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]);
    
    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;
    }
    
    return new Blob(Object.values(localStorage)).size;
    
    var warning = 1;
    var limit = 2000000; //2 million characters, not really taking in account to bytes but for tested ammounts 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