java - 在 sqlite3 数据库中读取 gzipped 字符串(python 写入,Java Android 读取)

标签 java android python sqlite gzip

我正在尝试通过压缩最小化包含大量 HTML 的 sqlite3 数据库。我使用 python 创建了 sqlite3 数据库,我正在尝试在 Android 上正确解压缩。

我使用 gzip 压缩 HTML 并将其作为 BLOB 存储在数据库中。这是我为创建 sqlite3 数据库(在 Python 中)编写的代码:

from sys import stdin, argv
import sqlite3
import gzip
import cStringIO

def compressBuf(buf):
    zbuf = cStringIO.StringIO()
    zfile = gzip.GzipFile(mode = 'wb',  fileobj = zbuf, compresslevel = 9)
    zfile.write(buf)
    zfile.close()
    return zbuf.getvalue()

conn = sqlite3.connect(argv[1])
conn.text_factory = str 
c = conn.cursor()

c.execute('''CREATE TABLE articles (
    id INTEGER NOT NULL PRIMARY KEY,
    name TEXT, category TEXT, html BLOB );''')

c.execute(' CREATE INDEX name_index on articles (name); ')

for line in stdin:
    line = line.strip().split('\t')
    line[-1] = sqlite3.Binary(compressBuf(line[-1]))    

    c.execute('INSERT INTO articles VALUES (?, ?, ?, ?);', line)

conn.commit()
c.close()
conn.close()

这是 Android 的代码 fragment :

Cursor cursor = db.rawQuery("SELECT html FROM articles WHERE id = " + id + " limit 1;", null);
cursor.moveToFirst();
byte[] zhtml = cursor.getBlob(0);
ByteArrayInputStream is = new ByteArrayInputStream(zhtml);
GZIPInputStream gis = new GZIPInputStream(is, zhtml.length);

我收到以下异常,提示 header 不正确:

 java.io.IOException: unknown format (magic number 213c)
   at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:84)
   at tw.cse.o0o.MyApp.WebServer$ArticleHandler$1.writeTo(WebServer.java:196)
   at org.apache.http.entity.EntityTemplate.writeTo(EntityTemplate.java:76)
   at org.apache.http.impl.entity.EntitySerializer.serialize(EntitySerializer.java:97)
   at org.apache.http.impl.AbstractHttpServerConnection.sendResponseEntity(AbstractHttpServerConnection.java:182)
   at org.apache.http.protocol.HttpService.handleRequest(HttpService.java:209)
   at tw.cse.o0o.MyApp.WebServer.run(SQLHelper.java:90)

使用 Python 解释器,我可以确认 compressBuf 函数返回正确的 gzip 魔数(Magic Number) 0x1f8b:

>>> compressBuf('test')
'\x1f\x8b\x08\x00 \xba:O\x02\xff+I-.\x01\x00\x0c~\x7f\xd8\x04\x00\x00\x00'

[编辑]

好的,这是我发现的:

在 Nexus One 上,getBlob() 函数会自动解压缩二进制数据,无论是 zlib 还是 gzip。错误日志中的 213c 是原始 html 的前两个字符。 但是,三星 Galaxy Tab(第一代)并非如此。我仍在尝试找到一种在我的 Galaxy Tab 上解压缩的方法..

最佳答案

'\x21\x3c -->> '!<'或者也许 '<!'取决于字节顺序。我建议您调查一下(二进制)gzip 数据在传输过程中被填充的可能性。

关于java - 在 sqlite3 数据库中读取 gzipped 字符串(python 写入,Java Android 读取),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9283269/

相关文章:

Java - java/lang/ProcessBuilder.<init>([Ljava/lang/String;)V 的这种用法可能容易受到命令注入(inject) (Sonar) 的攻击

java - 创建 hibernate 4 session 时出现异常

Java 字符串 "".value

java - 谷歌应用程序引擎Java - 使用低级API来获取数据 - 一些困难

python - ipywidgets,如何更改 slider 的值显示精度

android - 如果我对不同布局中的多个小部件使用相同的 ID 会怎样?

Android 模拟器不加载应用程序(崩溃报告)

android - Material Design 扩展 float 操作按钮没有涟漪效应

Python argparse 出现在 gc.garbage 中

python - 识别两个不同 CSV 的行中的重复项