#javascript #string #binaryfiles #web-sql
#javascript #строка #двоичные файлы #web-sql
Вопрос:
Мне нужно хранить строки JavaScript, содержащие двоичные данные, с помощью WebSQL. Я знаю, что можно использовать пользовательские технологии (IndexedDB, localStorage, …), Но по некоторым причинам мне нужно придерживаться WebSQL. Поскольку квота ограничена, и данные могут стать большими, я не хочу кодировать данные в Base64.
Рассмотрим следующий код JS (и соответствующий JSFiddle):
var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
function test(str){
db.transaction(function (tx) {
tx.executeSql('DROP TABLE IF EXISTS test');
tx.executeSql('CREATE TABLE test (val)');
tx.executeSql('INSERT INTO test(val) VALUES (?)',[str]);
tx.executeSql('SELECT val FROM test',[],function(tx,result){
var str2 = result.rows.item(0).val;
console.log(str " (" str.length ") - " str2 " (" str2.length ")");
});
});
}
test("Foo");
test("AB");
который выводит
Foo (3) — Foo (3)
AB (3) — A (1)
в Chrome и Safari.
Как вы можете видеть, нулевой байт и все символы после того, как он будет съеден WebSQL. Знаете ли вы, есть ли какой-либо способ поместить эту строку в WebSQL без ее увеличения (например, с помощью кодировки Base64) и без использования другой технологии хранения?
Ответ №1:
Единственный способ сохранить двоичные данные в websql — это кодировка base64. Если ваши данные действительно будут очень большими и могут превышать лимиты квот браузера на 5/10 МБ, преобразование base64 не будет основным виновником (оно просто раздувает данные в среднем в 4/3 раза). Если ваши исходные данные уже собираются пересечь квоты, вам лучше подумать о возможных обходных путях.
Комментарии:
1. смотрите мой собственный ответ, я заставил его работать без необходимости его повторного кодирования
Ответ №2:
На самом деле это работает. Проблема заключалась не в сохранении двоичной строки, а в ее извлечении. Когда результат содержал нулевой байт, строка считалась завершенной.
WebSQL предоставляет функцию as hex
, которая возвращает шестнадцатеричное представление строки. Например "AB"
, при сохранении функция вернет 410042. Используя это, я заставил свой пример работать (см. Обновленный JSFiddle):
//convert hex representation back to string
function hex2str(hex){
var result = new Array(hex.length / 2);
for(var i = 0, j = 0; j < hex.length; i , j =2)
result[i] = String.fromCharCode(parseInt(hex.substr(j,2),16));
return result.join("");
}
var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
function test(str){
db.transaction(function (tx) {
tx.executeSql('DROP TABLE IF EXISTS test');
tx.executeSql('CREATE TABLE test (val)');
tx.executeSql('INSERT INTO test(val) VALUES (?)',[str]);
//magic occurs here
tx.executeSql('SELECT hex(val) as val FROM test',[],function(tx,result){
var str2 = hex2str(result.rows.item(0).val);
console.log(str " (" str.length ") - " str2 " (" str2.length ")");
});
});
}
test("Foo"); //Foo (3) - Foo (3)
test("AB"); //AB (3) - AB (3)