web-dev-qa-db-fra.com

Calcul de l'utilisation de l'espace de stockage local

Je crée une application à l'aide de l'éditeur Bespin et du stockage local HTML5. Il stocke tous les fichiers localement et aide à la grammaire, utilise JSLint et certains autres analyseurs syntaxiques pour CSS et HTML pour aider l'utilisateur.

Je veux calculer combien de la limite de stockage local a été utilisée et combien il y a réellement. Est-ce possible aujourd'hui? Je pensais ne pas simplement calculer les bits stockés. Mais là encore, je ne suis pas sûr de savoir quoi de plus que je ne peux pas me mesurer moi-même.

72
JeroenEijkhof

Je n'ai pas trouvé de moyen universel d'obtenir la limite restante sur les navigateurs dont j'avais besoin, mais j'ai découvert que lorsque vous atteignez la limite, un message d'erreur apparaît. Ceci est bien sûr différent dans chaque navigateur.

Pour en tirer le maximum, j'ai utilisé ce petit script:

for (var i = 0, data = "m"; i < 40; i++) {
    try { 
        localStorage.setItem("DATA", data);
        data = data + data;
    } catch(e) {
        var storageSize = Math.round(JSON.stringify(localStorage).length / 1024);
        console.log("LIMIT REACHED: (" + i + ") " + storageSize + "K");
        console.log(e);
        break;
    }
}
localStorage.removeItem("DATA");

De cela, j'ai eu cette information:

Google Chrome

  • DOMException:
    • code: 22
    • message: "Echec de l'exécution de 'setItem' sur 'Storage': Le paramétrage de la valeur de 'data' a dépassé le quota."
    • nom: "QuotaExceededError"

Mozilla Firefox

  • DOMException:
    • code: 1014
    • message: "Taille maximale du stockage persistant atteinte"
    • nom: "NS_ERROR_DOM_QUOTA_REACHED"

Safari

  • DOMException:
    • code: 22
    • message: "QuotaExceededError: Exception DOM 22"
    • nom: "QuotaExceededError"

Internet Explorer, Edge (communauté)

  • DOMException:
    • code: 22
    • message: "QuotaExceededError"
    • nom: "QuotaExceededError"

Ma solution

Jusqu'à présent, ma solution consiste à ajouter un appel supplémentaire chaque fois que l'utilisateur économise quelque chose. Et si l'exception est interceptée, je leur dirais qu'elles sont à court de capacité de stockage.


Edit: Supprimer les données ajoutées

J'ai oublié de mentionner que pour que cela fonctionne réellement, vous devez supprimer l'élément DATA qui avait été défini à l'origine. La modification est reflétée ci-dessus en utilisant la fonction removeItem () .

47
JeroenEijkhof

Vous pourrez peut-être avoir une idée approximative en utilisant les méthodes JSON pour transformer l'objet localStorage entier en une chaîne JSON:

JSON.stringify(localStorage).length

Je ne sais pas à quel point il serait précis en octets, en particulier avec les quelques octets de balises ajoutées si vous utilisez des objets supplémentaires - mais je suppose que c'est mieux que de penser que vous ne faites que pousser 28K et que vous faites plutôt 280K (ou vice-versa). vice versa).

67
Morgon

IE8 implémente la propriété remainingSpace à cette fin:

alert(window.localStorage.remainingSpace);  // should return 5000000 when empty

Malheureusement, il semble que cela ne soit pas disponible dans les autres navigateurs. Cependant, je ne suis pas sûr qu'ils mettent en œuvre quelque chose de similaire.

26
Daniel Vassallo

Vous pouvez utiliser la ligne ci-dessous pour calculer avec précision cette valeur et voici un jsfiddle pour illustrer son utilisation

alert(1024 * 1024 * 5 - escape(encodeURIComponent(JSON.stringify(localStorage))).length);
12
jas-

Couru dans ce aujourd'hui tout en testant (dépassant le quota de stockage) et concocté une solution. OMI, savoir quelle est la limite et où nous en sommes est beaucoup moins utile que de mettre en place un moyen fonctionnel de continuer à stocker au-delà du quota.

Ainsi, plutôt que d'essayer de faire des comparaisons de taille et des vérifications de capacité, laissez-nous réagir lorsque nous avons atteint le quota, réduire notre stockage actuel d'un tiers et reprendre le stockage. Si cette réduction échoue, arrêtez de stocker.

set: function( param, val ) { 
    try{
        localStorage.setItem( param, typeof value == 'object' ? JSON.stringify(value) : value )
        localStorage.setItem( 'lastStore', new Date().getTime() )
    }
    catch(e){
      if( e.code === 22 ){
        // we've hit our local storage limit! lets remove 1/3rd of the entries (hopefully chronologically)
        // and try again... If we fail to remove entries, lets silently give up
        console.log('Local storage capacity reached.')

        var maxLength = localStorage.length
          , reduceBy = ~~(maxLength / 3);

        for( var i = 0; i < reduceBy; i++ ){
          if( localStorage.key(0) ){
            localStorage.removeItem( localStorage.key(0) );
          }
          else break;
        }

        if( localStorage.length < maxLength ){
          console.log('Cache data reduced to fit new entries. (' + maxLength + ' => ' + localStorage.length + ')');
          public.set( param, value );
        }
        else {
          console.log('Could not reduce cache size. Removing session cache setting from this instance.');
          public.set = function(){}
        }
      }
    }
}

Cette fonction vit dans un objet wrapper, alors public.set s’appelle tout simplement. Maintenant, nous pouvons ajouter au stockage et ne pas nous inquiéter du quota ou de la proximité avec ce dernier. Si un magasin dépasse le 1/3, la taille du quota correspond au point où cette fonction arrêtera le tri et arrêtera le stockage. À ce stade, vous ne devriez pas mettre en cache de toute façon, non?

8
Shiboe

Pour ajouter des résultats de test au navigateur:

Firefox I = 22.

Safari La version 5.0.4 n’a pas été bloquée sur mon Mac. Erreur en tant que Chrome. i = 21.

Opera .__ indique à l'utilisateur que le site Web souhaite stocker des données mais ne dispose pas de suffisamment d'espace. L'utilisateur peut refuser la demande, dans la limite du montant requis ou de plusieurs autres limites, ou le définir en illimité. Allez à opera: webstorage pour dire si ce message apparaît ou non. i = 20. L'erreur renvoyée est identique à celle de Chrome.

Mode standard IE9 Erreur en tant que Chrome. i = 22.

IE9 en mode standard IE8 Message de la console "Erreur: l'espace de stockage est insuffisant pour terminer cette opération". i = 22

IE9 dans les anciens modes Erreur d’objet. i = 22.

IE8 Vous n'en avez pas de copie à tester, mais le stockage local est pris en charge (http://stackoverflow.com/questions/3452816/does-ie8-support-out-of-the-box-in -stockage local)

IE7 et versions antérieures Ne prend pas en charge le stockage local.

5
user535673

Vous pouvez tester votre navigateur avec ce test test de support de stockage Web

J'ai testé Firefox sur ma tablette Android et sur l'ordinateur portable Windows et Chromium uniquement sur Windows Résultats:

  1. Firefox (Windows):

    • localStorage: 5120k car
    • sessionStorage: 5120k car
    • localStorage: * non pris en charge
  2. Firefox (Android):

    • localStorage: 2560k caractères
    • sessionStorage: Illimité (le test s'exécute exactement jusqu'à 10240k car == 20480k octets)
    • localStorage: non pris en charge
  3. Chrome (fenêtres):

    • localStorage: 5120k car
    • sessionStorage: 5120k car
    • localStorage: non pris en charge

Mettre à jour

Sur Google Chrome Version 52.0.2743.116 m (64 bits) limites où un peu plus bas sur 5101k caractères. Cela signifie que max disponible peut changer de version.

3
Morteza Tourani

Je voudrais pouvoir ajouter ceci dans un commentaire - pas assez de représentants, désolé.

J'ai effectué quelques tests de performance - en supposant que JSON.stringify (localStorage) .length soit une opération coûteuse pour une grande occupation de LocalStorage. 

http://jsperf.com/occupied-localstorage-json-stringify-length

En effet, il coûte environ 50 fois plus cher que de garder une trace de ce que vous stockez, et le stockage local plus complet devient encore pire.

2
SashaK

Cette fonction obtient le exact mémoire disponible/à gauche:

J'ai créé une suite de fonctions utiles pour localStorage * here *

http://jsfiddle.net/kzq6jgqa/3/

function getLeftStorageSize() {
    var itemBackup = localStorage.getItem("");
    var increase = true;
    var data = "1";
    var totalData = "";
    var trytotalData = "";
    while (true) {
        try {
            trytotalData = totalData + data;
            localStorage.setItem("", trytotalData);
            totalData = trytotalData;
            if (increase) data += data;
        } catch (e) {
            if (data.length < 2) break;
            increase = false;
            data = data.substr(data.length / 2);
        }
    }
    localStorage.setItem("", itemBackup);

    return totalData.length;
}

// Examples
document.write("calculating..");
var storageLeft = getLeftStorageSize();
console.log(storageLeft);
document.write(storageLeft + "");

// to get the maximum possible *clear* the storage 
localStorage.clear();
var storageMax = getLeftStorageSize();

Notez que ce n'est pas très rapide, alors ne l'utilisez pas tout le temps.

Grâce à cela, j'ai également découvert que: le nom de l'élément occupera autant d'espace que sa longueur, la valeur de l'élément occupera également autant de place que leur longueur.

Le stockage maximum que j'ai eu - tout environ 5M:

  • 5000000 caractères - Edge
  • 5242880 caractères - Chrome
  • 5242880 caractères - Firefox
  • 5000000 caractères - IE

Vous trouverez du code commenté dans le violon pour voir la progression dans la console.

Cela m'a pris du temps à faire, espérons que cela aide

1
CoderPi

J'avais besoin de simuler et de tester ce que mon module ferait quand le stockage serait plein. Je devais donc avoir une précision précise sur le moment où le stockage était plein, plutôt que la réponse acceptée, qui perd cette précision à un taux de 1 ^ 2.

Voici mon script, qui devrait toujours produire une précision de 10 lorsque la limite de mémoire est atteinte, et assez rapidement malgré quelques optimisations simples ... EDIT: J'ai amélioré le script et avec une précision exacte:

function fillStorage() {
    var originalStr = "1010101010";
    var unfold = function(str, times) {
        for(var i = 0; i < times; i++)
            str += str;
        return str;
    }
    var fold = function(str, times) {
        for(var i = 0; i < times; i++) {
            var mid = str.length/2;
            str = str.substr(0, mid);
        }
        return str;
    }

    var runningStr = originalStr;
    localStorage.setItem("filler", runningStr);
    while(true) {
        try {
            runningStr = unfold(runningStr, 1);
            console.log("unfolded str: ", runningStr.length)
            localStorage.setItem("filler", runningStr);
        } catch (err) {
            break;
        }
    }

    runningStr = fold(runningStr, 1);  
    var linearFill = function (str1) {
        localStorage.setItem("filler", localStorage.getItem("filler") + str1);
    }
    //keep linear filling until running string is no more...
    while(true) {
        try {
            linearFill(runningStr)
        } catch (err) {
            runningStr = fold(runningStr, 1);
            console.log("folded str: ", runningStr.length)
            if(runningStr.length == 0)
                break;
        }
    }

    console.log("Final length: ", JSON.stringify(localStorage).length)
}
1
balthatrix
 try {
     var count = 100;
     var message = "LocalStorageIsNOTFull";
     for (var i = 0; i <= count; count + 250) {
         message += message;
         localStorage.setItem("stringData", message);
         console.log(localStorage);
         console.log(count);
     }

 }
 catch (e) {
     console.log("Local Storage is full, Please empty data");
     // fires When localstorage gets full
     // you can handle error here ot emply the local storage
 }
0
jinal

Cela pourrait aider quelqu'un. En chrome est possible de demander à l'utilisateur d'autoriser l'utilisation de plus d'espace disque si nécessaire:

// Request Quota (only for File System API)  
window.webkitStorageInfo.requestQuota(PERSISTENT, 1024*1024, function(grantedBytes) {
  window.webkitRequestFileSystem(PERSISTENT, grantedBytes, onInitFs, errorHandler); 
}, function(e) {
  console.log('Error', e); 
});

Consultez la page https://developers.google.com/chrome/whitepapers/storage#asking_more pour plus d'informations.

0
Remo H. Jansen