首页 文章

使用localStorage进行javascript字符串压缩

提问于
浏览
18

我在项目中使用 localStorage ,它需要存储大量数据,主要是int,bool和string类型 . 我知道javascript字符串是unicode,但是当存储在 localStorage 中时,它们是否保持unicode?如果是这样,有没有办法可以压缩字符串以使用unicode字节中的所有数据,或者我应该只使用base64并减少压缩?所有数据都将存储为一个大字符串 .

编辑:现在我考虑一下,base64根本不会做太多压缩,数据已经在64位, a-zA-Z0-9 ;: 是65个字符 .

5 回答

  • 6

    您可以编码到Base64,然后实现一个简单的无损压缩算法,如行程编码或Golomb编码 . 这不应该太难做,可能会给你一点压力 .

    Golomb encoding

    我也找到了JsZip . 我想你可以查看代码并只使用算法,如果它是兼容的 .

    希望这可以帮助 .

    http://jszip.stuartk.co.uk/

  • 0

    我最近不得不在localStorage中保存巨大的JSON对象 .

    首先,是的,他们确实保持unicode . 但是不要试图将对象直接保存到本地存储 . 它需要是一个字符串 .

    在将对象转换为字符串之前,我使用了一些压缩技术(在我的情况下看起来效果很好):

    通过执行类似(num).toString(36)的操作,可以将任何数字从10的基数转换为36的基数 . 例如,数字48346942将是“ss8qm”,即(包括引号)少1个字符 . 添加引号可能实际上会增加字符数 . 所以数字越大,收益越好 . 要将其转换回来,您可以执行类似parseInt(“ss8qm”,36)的操作 .

    如果要存储具有任何将重复的键的对象,则最好创建一个查找对象,在该对象中为原始项指定缩短的键 . 所以,举例来说,如果你有:

    {
        name: 'Frank',
        age: 36,
        family: [{
            name: 'Luke',
            age: 14,
            relation: 'cousin'
        }, {
            name: 'Sarah',
            age: 22,
            relation: 'sister'
        }, {
            name: 'Trish',
            age: 31,
            relation: 'wife'
        }]
    }
    

    然后你可以做到:

    {
        // original w/ shortened keys
        o: {    
            n: 'Frank',
            a: 36,
            f: [{
                n: 'Luke',
                a: 14,
                r: 'cousin'
            }, {
                n: 'Sarah',
                a: 22,
                r: 'sister'
            }, {
                n: 'Trish',
                a: 31,
                r: 'wife'
            }]
        },
    
        // lookup
        l: {
            n: 'name',
            a: 'age',
            r: 'relation',
            f: 'family'
        }
    }
    

    再次,这与尺寸有关 . 并重复 . 就我而言,它的效果非常好 . 但这取决于主题 .

    所有这些都需要一个缩小功能,一个需要扩展 .

    另外,我建议创建一个用于存储和检索本地存储数据的类 . 我跑到那里没有足够的空间 . 所以写入会失败 . 其他站点也可能写入本地存储,这可能会占用一些空间 . 有关详细信息,请参阅this post .

    在我构建的课程中,我所做的是首先尝试使用给定的键删除任何项目 . 然后尝试setItem . 这两行用try catch包裹 . 如果失败则假定存储已满 . 然后它会清除localStorage中的所有内容,以便为它腾出空间 . 然后,在清除之后,再次尝试setItem . 这也包含在try catch中 . 因为如果字符串本身大于localStorage可以处理的字符串,它可能会失败 .

    编辑:此外,你会遇到很多人提到的LZW压缩 . 我实现了它,它适用于小字符串 . 但是对于大字符串,它会开始使用无效字符,从而导致数据损坏 . 所以要小心,如果你去那个方向测试测试

  • 0

    This Stackoverflow Question有一个可能有帮助的答案 . 有一个JavaScript压缩库的链接 .

  • 7

    javascript的Base64压缩很好地解释at this blog . 使用整个framework时,实现也是available here .

  • 23

    "when stored in localStorage, do they stay unicode?"

    Web Storage working draft将本地存储值定义为DOMString . DOMStrings are defined作为使用UTF-16 encoding的16位单元的序列 . 所以,是的,他们保持Unicode .

    is there a way I could compress the string to use all of the data in a unicode byte ... ?

    "Base32k"编码应该为每个字符提供15位 . base32k类型编码利用UTF-16字符的全16位,但丢失了一点以避免双字符跳闸 . 如果原始数据是base64编码的,则每个字符仅使用6位 . 将这6位编码到base32k中应该将其压缩到原始大小的6/15 = 40% . 见http://lists.xml.org/archives/xml-dev/200307/msg00505.htmlhttp://lists.xml.org/archives/xml-dev/200307/msg00507.html .

    为了进一步减小大小,您可以将base64字符串解码为完整的8位二进制文件,使用一些已知的压缩算法(例如参见javascript implementation of gzip)对其进行压缩,然后对压缩输出进行base32k编码 .

相关问题