Хранение строк JS, содержащих двоичные данные, в WebSQL

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