Чтение сжатой строки в базе данных sqlite3 (запись на python, чтение Java Android) - PullRequest
5 голосов
/ 14 февраля 2012

Я пытаюсь минимизировать sqlite3 db с большим количеством HTML-файлов путем сжатия. Я использовал 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:

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

Я получаю следующее исключение, жалуясь на неправильный заголовок:

 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 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. Тем не менее, это не относится к Samsung Galaxy Tab (первого поколения). Я все еще пытаюсь найти способ распаковать на моем Galaxy Tab ..

1 Ответ

0 голосов
/ 15 февраля 2012

'\x21\x3c - >> '!<' или, возможно, '<!' в зависимости от порядка байтов. Я предлагаю вам изучить возможность того, что (двоичные) сжатые данные были переданы при передаче.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...