如何找到localStorage的大小

der*_*ion 101 javascript html5 local-storage

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

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

Ser*_*kyy 189

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

或者在书签的"位置"字段中添加此文本以方便使用

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

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

PPS应该适用于Chrome和Firefox.

  • 这是一个修改版本,也考虑了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");` (16认同)
  • 将其粘贴到控制台中以查看总数:var t = 0; for(var x in localStorage){t + =(((localStorage [x] .length*2))); } console.log(t/1024 +"KB"); (8认同)
  • @Micah Javascript在内部使用UTF16,因此每个字符都存储为两个字节,您需要将字符数乘以2以获得实际使用的空间.(你可能已经发现了这一点,但我认为这里值得注意的只是其他人有同样的问题) (5认同)
  • @Serge,这个答案投票最多,因此在这里张贴`var t = 0; for(var x in localStorage){t + =(x.length + localStorage [x] .length)*2; } console.log(t/1024 +"KB");` (2认同)

ten*_*ent 45

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

我的回归: "30.896484375 KB"


Ada*_*dam 18

IE具有Storage对象的remainingSpace属性.其他浏览器目前没有等效.

我相信默认的空间量是5MB,虽然我还没有亲自测试过.

  • 请注意,localStorage.remainingSpace属性返回存储对象允许的剩余UTF-16字符数.不是以字节为单位的剩余大小.[参考文献](https://msdn.microsoft.com/en-us/library/cc197016(V = VS.85)的.aspx) (2认同)

jas*_*as- 14

这是一个如何执行此操作的简单示例,应该适用于每个浏览器

alert(1024 * 1024 * 5 - unescape(encodeURIComponent(JSON.stringify(localStorage))).length);
Run Code Online (Sandbox Code Playgroud)

  • 此示例错误地假定localStorage在每个浏览器中具有5MB(5*1024*1024)的相同固定限制. (5认同)

小智 12

希望这能有所帮助.

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

并且正如上面所承诺的那样,在不同的浏

GalaxyTab 10.1

  • Maxthon Pad 1.7~1130ms 5Mb
  • Firefox 20.0(Beta 20.0)崩溃了
  • Chrome 25.0.1364.169~22250ms/5Mb
  • Native(标识为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双核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的时候,但如果我们想要增加lS的数量,Opera会很好地问,不幸的是如果测试连续进行几次就会崩溃)

赢8(在Parallels 8下)

  • IE10~7850ms /9.54Mb


小智 6

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

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

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


Jed*_*Jed 5

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

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'));
            
            //Recommended by @pkExec and @jrob007
            localStorage.setItem(testQuotaKey, String('1').repeat(tryByteSize));
            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;
}
Run Code Online (Sandbox Code Playgroud)

  • Array.join 是一个性能杀手,最好在可用的情况下使用 String.repeat (这意味着除了 IE 之外的所有地方) (2认同)

P R*_*tto 5

您可以使用Blob函数获取本地存储数据的当前大小在旧的浏览器中,这可能不起作用。

例:

return new Blob(Object.values(localStorage)).size;
Run Code Online (Sandbox Code Playgroud)

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

  • 我认为“Blob”并不将字符串编码限制为 UTF-16,因此这实际上可能是最可靠的方法。`new Blob(['X']).size;` = 1 而 `new Blob(['☃']).size` (U+2603 / 雪人字符) ==&gt; 3. 基于 `String.prototype 的解决方案.length` 不考虑这一点(处理“字符”),而存储配额/限制可能会考虑这一点(处理字节),我可以想象这会导致意外,例如,在存储非英语/ASCII 字符时。 (3认同)
  • `Blob` 将包含一个文本。UTF-8 文本。而 `localStorage` 将值存储为 UTF-16。因此,它会以大约 2 倍的小值打印该值。 (3认同)
  • 为什么只有价值观?那么我们还需要将它们包含在计算中的键呢?a = { a:[1,2,3,4], b:未定义, c:null, d:5, e:"aAbBCcDd&amp;90", f:-10, h:10.10, i:-10.10, }; s = new Blob(Object.values(a)).size + new Blob(Object.keys(a)).size; console.log("大小:",s); (2认同)