LocalStorage boyutu nasıl bulunur


118

Şu anda HTML5'in localStorage'ını kullanacak bir site geliştiriyorum. Farklı tarayıcılar için boyut sınırlamaları hakkındaki her şeyi okudum. Ancak, localStorage örneğinin mevcut boyutunu nasıl bulacağıma dair hiçbir şey görmedim. Bu soru , JavaScript'in belirli bir değişkenin boyutunu göstermek için yerleşik bir yolunun olmadığını gösteriyor gibi görünüyor. LocalStorage'ın görmediğim bir bellek boyutu özelliği var mı? Kaçırdığım bunu yapmanın kolay bir yolu var mı?

Sitem, kullanıcıların 'çevrimdışı' modda bilgi girmelerine izin vermeyi amaçlamaktadır, bu nedenle, depolama alanı neredeyse dolduğunda onlara bir uyarı verebilmek çok önemlidir.


Yanıtlar:


222

Bu parçacığı JavaScript konsolunda çalıştırın (tek satırlı sürüm):

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");

Sake okumak için birden çok satırda aynı kod

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");

veya bu metni rahat kullanım için bir yer iminin 'konumu' alanına ekleyin

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")); 

PS Parçacıkları yorumdaki talebe göre güncellenir. Şimdi hesaplama, anahtarın kendisinin uzunluğunu içerir. Javascript'teki karakter UTF-16 olarak saklandığından (2 bayt kaplar) her uzunluk 2 ile çarpılır.

PPS hem Chrome hem de Firefox'ta çalışmalıdır.


8
Toplamı görmek için bunu konsola yapıştırın: var t = 0; for (localStorage'daki var x) {t + = (((localStorage [x] .length * 2))); } console.log (t / 1024 + "KB");
Henry

5
@Micah Javascript, UTF16'yı dahili olarak kullanır, bu nedenle her karakter iki bayt olarak saklandığından, kullanılan gerçek alanı elde etmek için karakter sayısını ikiyle çarpmanız gerekir. (Muhtemelen bunu zaten keşfetmişsinizdir, ancak burada aynı soruyu soran başka biri için burada kayda değer olduğunu düşündüm)
Rebecka

2
@Serge, bu cevap en çok oy verildiği için burada yayınlanıyor var t = 0; for(var x in localStorage) { t += (x.length + localStorage[x].length) * 2; } console.log(t/1024+ " KB");
Mihir

17
İşte 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");
NaN'yi

1
Yer iminde bir hata var. Ana kodda altı çizili değişkenler ve yer iminde normal isimler kullanıyorsunuz. Tek altı çizili _xonu kırar. Alt çizgiyi kaldırmanız yeterlidir.
Soul Reaver

46

@Shourav'ın yukarıda söylediklerinden yola çıkarak, tüm localStorageanahtarlarınızı (mevcut etki alanı için) doğru bir şekilde yakalaması ve localStoragenesnenizin tam olarak ne kadar bellek kapladığını bilmeniz için birleşik boyutu hesaplaması gereken küçük bir işlev yazdım :

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)';
    };

Maden geri döndü: "30.896484375 KB"


1
Teşekkürler @tennisgent. Benimki IE11, FF> 26 ve Chrome için de çalıştı.
Akki922234

18

IE, Storage nesnesinin kalanSpace özelliğine sahiptir. Diğer tarayıcıların şu anda eşdeğeri yok.

Kişisel olarak test etmemiş olmama rağmen varsayılan alan miktarının 5MB olduğuna inanıyorum.


1
Bu yalnızca bir IE özelliği
jas-

site başına 5 mb sınır mı yoksa tüm siteler için genel mi?
divyenduz

@divyenduz, sanırım
Adam

2
LocalStorage.remainingSpace özelliğinin, depolama nesnesi için izin verilen kalan UTF-16 karakter sayısını döndürdüğünü unutmayın. Bayt cinsinden kalan boyut DEĞİL. Referans
Mihir

14

İşte bunun nasıl yapılacağına dair basit bir örnek ve her tarayıcıyla çalışmalıdır

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

orada bir yerde * 8'e ihtiyacın yok mu?
George Mauer


Bu, boyutu bayt cinsinden mi yoksa bit cinsinden mi verir?
JamesTheAwesomeDude

6
Bu örnek hatalı bir şekilde localStorage'ın her tarayıcıda 5MB'de (5 * 1024 * 1024) aynı sabit limite sahip olduğunu varsayar.
Victor

Bu, w3c'nin ortaya koyduğu spesifikasyona göre.
jas-

13

Umarım bu birine yardımcı olur.

Jsfiddle'daki Jas- example benim için işe yaramadığı için bu çözümü buldum. (Aşağıdaki kodda kullandığım bitleri için Serge Seletskyy ve Shourav'a teşekkürler)

Aşağıda localStorage için ne kadar alan kaldığını ve (eğer herhangi bir anahtar zaten lS'de ise) ne kadar alan kaldığını test etmek için kullanılabilecek fonksiyon aşağıdadır.

Biraz kaba bir güç ama Firefox dışında hemen hemen her tarayıcıda çalışıyor. Masaüstü FF'de tamamlanması uzun sürüyor (4-5 dakika) ve Android'de çöküyor.

İşlevin altında, farklı platformlarda farklı tarayıcılarda yaptığım testlerin kısa bir özeti var. Zevk almak!

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
}

Ve yukarıda söz verildiği gibi, farklı tarayıcılarda bazı testler:

GalaxyTab 10.1

  • Maxthon Pad 1.7 ~ 1130ms 5Mb
  • Firefox 20.0 (Beta 20.0) her ikisini de kilitledi
  • Chrome 25.0.1364.169 ~ 22250ms / 5Mb
  • Yerel (Safari 4.0 / Webkit534.30 olarak tanımlanır) ~ 995ms / 5Mb

iPhone 4s iOS 6.1.3

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

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

  • Safari 6.0.3 ~ 105ms / 5Mb
  • Chrome 26.0.1410.43 ~ 3400ms / 5Mb
  • Firefox 20.0 300150ms (!) / 10Mb (betiğin uzun süre çalışmasından şikayet ettikten sonra)

iPad 3 iOS 6.1.3

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

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

  • Safari 5.1.7 ~ 80ms / 5Mb
  • Chrome 26.0.1410.43 ~ 1220ms / 5Mb
  • Firefox 20.0 228500ms (!) / 10Mb (komut dosyasının uzun süre çalışmasından şikayet ettikten sonra)
  • IE9 ~ 17900ms /9.54Mb (kodda herhangi bir console.log varsa DevTools açılana kadar çalışmaz)
  • Opera 12.15 ~ 4212ms /3.55Mb (bu 5Mb seçildiğinde olur, ancak Opera lS miktarını artırmak isteyip istemediğimizi güzelce sorar, ne yazık ki test arka arkaya birkaç kez yapılırsa çöker)

Kazanın 8 (Paralellikler Altında 8)

  • IE10 ~ 7850ms /9.54Mb

Harika deneyler. Bununla birlikte array.forEach(), kodunuzda bulduğum , IE'de olmadığını bildiğim için, kendiniz uyguluyor musunuz? Genel gecikmeye katkısını nasıl ölçüyorsunuz?
Evi Song

Teşekkürler, ilk testlerden bir süre geçtiği için onları yeniden yapabilirim. Gelince forEach(). Hayır kendim uygulamadım, hisseyi kullandım Array.prototype.forEach(). Mozilla Developer Network aka IE9'dan MDN'ye göre yerel desteğe sahiptir.
Jakub Gadkowski

Teşekkürler. Bilgimin yenilenmesi gerekiyor. Daha sonra Array.prototype.forEach()projem erken IE sürümlerini desteklemiyorsa mümkün olduğunca kullanacağım.
Evi Song

Kod önemli ölçüde daha hızlı yapılabilir (Firefox'ta ~ 2500ms, Chrome'da ~ 700ms): whiledöngüyü iki kısma ayırın , ilki stackoverflow.com/a/3027249/1235394'teki gibi localStorage'ı üssel olarak büyüyen veri yığınlarıyla doldurur, ardından ikinci kısım Depoyu tamamen doldurmak için sabit boyutlu küçük parçalar. Test sayfası: jsfiddle.net/pqpps3tk/1
Victor

IE10 Rocks .. Yine de, Chrome'u indirmek için en hızlı tarayıcı :)
Ruslan Abuzant

11

Blob işlevini kullanarak yerel depolama verilerinin mevcut boyutunu elde edebilirsiniz . Bu, eski tarayıcılarda çalışmak için destek kontrol olmayabilir new Blobve Object.values()caniuse de.

Misal:

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

Object.values ​​() localStorage nesnesini bir diziye dönüştürür. Blob, diziyi ham verilere dönüştürür.


3
BlobDize kodlamasını UTF-16 ile kısıtlamadığını düşünüyorum , bu yüzden bu aslında en güvenilir yöntem olabilir. new Blob(['X']).size;= 1 oysa new Blob(['☃']).size(U + 2603 / kardan adam karakteri) ==> 3. Temel alan çözümler String.prototype.lengthbunu hesaba katmaz ("karakterlerle" ilgilenir), oysa depolama kotaları / limitleri büyük olasılıkla (baytlarla ilgilenir) ve hayal edebiliyorum Bu, örneğin İngilizce olmayan / ASCII karakterleri depolarken sürprizlere yol açar.
iX3

Chrome ve FF'de Blob çözümünü test etmek için localStorage boyutunu dize uzunluğuyla hesaplayan Jed'in cevabını kullandım. İlk testte localStorage'ı '1' işaretiyle doldurdum. ikinci testte, localStorage'ı Blob nesnesinde daha büyük boyuta sahip olan '' ☃ '' işaretiyle doldurdum. Her iki durumda da tam olarak aynı maksimum localStorage uzunluğuna sahibim. Dolayısıyla karakterlerin Blob boyutu localStorage sınırlamasını etkilemez. Bu nedenle Blob bu amaçla kullanılmamalıdır.
Vincente

6

Yerel deponuzu aşağıdaki yöntemleri kullanarak hesaplayabilirsiniz:

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());

Son olarak, bayt cinsinden boyut tarayıcıya girilecektir.


4

Hepsini alan ve içeriği sayan @tennisgen kodunu kullanırdım, ancak anahtarları kendim sayarım:

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)';
    };

3

Bu problemi çözme şeklim, Yerel Depolamada kullanılan alanı ve kalan alanı bulmak için işlevler ve ardından maksimum depolama alanını belirlemek için bu işlevleri çağıran bir işlev oluşturmaktı.

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 bir performans katilidir, kullanılabildiği yerde String.repeat'i daha iyi kullanın (bu, IE dışında her yerde anlamına gelir)
pkExec

2

Burada en çok oylanan @ serge'nin cevabına ek olarak, anahtarların boyutu da dikkate alınmalıdır. Aşağıdaki kod, içinde depolanan anahtarların boyutunu ekleyecektir.localStorage

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

Ben Firefox döner tespit ettik undefinedöğe için lengthbazı durumlarda, bu yüzden ek bir koşullu ekledik: t += (x.length + (this.storage[x].length ? this.storage[x].length : 0)) * 2;.
camilokawerin

@camilokawerin, depoda tanımsız bir değer kaydedilmediği sürece olmamalıdır, çünkü String localStorage ile desteklenen tek türdür ve String, Length özelliğine sahiptir. Jsfiddle veya benzeri bir şey hakkında bir örnek yayınlayabilir misiniz?
Mihir

1

Spesifikasyon giderken, bir dizenin her karakteri 16 bittir.

Ancak chrome ile inceleme (Ayarlar> İçerik Ayarları> Çerezler ve Site verileri) bize localStorage'ı başlatmanın 3kB (ek yük boyutu) sürdüğünü gösteriyor

Ve depolanan veri boyutu bu ilişkiyi takip eder (1kB'ye kadar doğru)
3 + ((localStorage.x.length * 16) / (8 * 1024)) kB

localStorage.x sizin depolama dizenizdir.


0

// Bellek hem anahtar hem de değer tarafından işgal edilir, bu nedenle Güncellenmiş Kod.

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]);

0

Evet, bu soru 10 yıl önce sorulmuştu. Ancak ilgilenenler (benim gibi, verileri yerel depolamayla kaydeden çevrimdışı bir metin düzenleyici oluşturduğum için) ve programlamada kötü olanlar için, bunun gibi basit bir şey kullanabilirsiniz:

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

Doldurulan depolama miktarını almanın en iyi yolu, site ayarlarını görüntülemektir (örneğin, yerel depoda bir görüntü sakladıysanız). En azından Chrome'da kullanılan bayt miktarını görebilirsiniz (yani: 1222 bayt). Bununla birlikte, js ile doldurulmuş yerel depolamayı görmenin en iyi yolları yukarıda zaten belirtilmişti, bu yüzden onları kullanın.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.