Открытие данных BLOB-объектов, хранящихся в Sqlite, в виде файла с помощью Tcl/Tk

Я использую следующий код tcl для сохранения файла с моего рабочего стола в базу данных Sqlite в виде данных большого двоичного объекта ($fileText — это путь к текстовому файлу):

sqlite3 db Docs.db
set fileID [open $fileText RDONLY]
fconfigure $fileID -translation binary
set content [read $fileID]
close $fileID
db eval {insert into Document (Doc) VALUES ($content)}
db close

Я нашел много ресурсов о том, как открыть данные большого двоичного объекта для чтения и записи, но я не могу найти никаких ресурсов по открытию данных большого двоичного объекта в виде файла. Например, если бы $fileText был pdf, как бы я открыл его из Sqlite как pdf?


person user175328    schedule 17.05.2010    source источник


Ответы (1)


Когда вы говорите «открыть как PDF», я предполагаю, что вы хотите, чтобы какая-то внешняя программа видела данные в виде файла? Единственные способы сделать это:

  1. Проделайте какие-нибудь хитрые махинации с файловыми системами пользовательского режима в Linux (или эквивалентными в вашей ОС), чтобы можно было смонтировать базу данных, или
  2. Скопируйте данные из базы данных во временный файл с правильным именем (подсказка: сохраните его как отдельный столбец в этой таблице).

Там также представлено все это как веб-сервер, но это действительно второе с браузером в миксе; данные все равно копируются.

С другой стороны, если все, что вы хотите сделать, это иметь данные в виде потока, который вы можете читать или записывать из Tcl, в пакете sqlite3 есть то, что вам нужно:

dbcmd incrblob ?-readonly? ?db? table column rowid

Который возвращает стандартный дескриптор канала (хотя и не подкрепленный дескриптором ОС, поэтому будьте осторожны при использовании в качестве перенаправления с exec).


[EDIT]: вот как получить данные (конечно, замените ... предложением, чтобы получить правильную строку):

# Open the DB
sqlite3 db Docs.db

# Open the file to write to
set fileID [open $fileText w]
fconfigure $fileID -translation binary

# Write the BLOB
db eval {SELECT Doc FROM Document WHERE ... LIMIT 1} row {
    puts -nonewline $fileID $row(Doc)
}

# We're done!
close $fileID
db close

Не беспокойтесь о размере BLOB; пакет Tcl sqlite3 эффективно передает его. Если вы все еще обеспокоены, вот другой способ (опять же, вам нужно заменить ... соответствующим образом):

# Open the DB
sqlite3 db Docs.db

# Open the file to write to
set fileOut [open $fileText w]
fconfigure $fileOut -translation binary

# Get the BLOB as a (read-only) channel
set fdBlob [db incrblob -readonly Document Doc ...]
fconfigure $fdBlob -translation binary

# Do the copy 
fcopy $fileOut $fdBlob

# We're done!
close $fdBlob
close $fileOut
db close
person Donal Fellows    schedule 17.05.2010
comment
Привет Дональд - спасибо за ваш отзыв. Я надеялся разработать интерфейс tcl tk, который позволил бы конечному пользователю загружать pdf-файл (в sqlite), а затем иметь возможность загружать pdf-файл для использования, как стандартную файловую базу данных. Часть загрузки кажется достаточно простой, используя двоичные данные/данные BLOB-объектов. Я могу делать что-то не так. Является ли открытие канала ввода-вывода моим единственным вариантом с данными BLOB-объектов или данные можно открыть в виде файла, аналогично открытию файла из веб-базы данных? - person DFM; 18.05.2010
comment
@DFM: SQLite хранит BLOB в базе данных, поэтому открыть его как файл напрямую не получится (ну, не без вопиющих хаков, как в пункте 1 моего ответа). Скопируйте его. NB: копирование — это всего несколько строк кода. - person Donal Fellows; 18.05.2010
comment
Привет, Дональд. Копирование данных работает хорошо. В качестве теста вместо puts... я скопировал его в виджет текстового поля, так как я не использую оболочку. Я обнаружил, что при копировании данных BLOB-объектов в формате PDF или Word появляются нераспознанные символы, скорее всего, из-за формата. Как мне скомпилировать эти данные обратно в документ PDF или Word? - person user175328; 18.05.2010