Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > Открыть blob поле в соответствующим ему приложении


Автор: Gella7 22.9.2009, 09:47
Я загружаю файл в blob. Файлы могут быть разнве - текстовые, архивы, jpg, pdf....

к примеру файл с расширением djvu

Код

      DataModule2.IBTable1.Append;
      DataModule2.IBTable1File1.LoadFromFile('C:\Nest\nest.djvu');
      DataModule2.IBTable1op.Value := 'djvu';
      DataModule2.IBTable1.Post;



Нужно сделать так, чтобы, допустим при щелчке на кнопку (не важно) файл открывался в соответствующем ему приложении.
Я пока только сделала пересохранение, тоесть берем файл и сохраняем с соответствующим расширением:

Код

Procedure TForm1.Button2Click(Sender: TObject);
Var
FName: string;
Begin
  If (SaveDialog1.Execute) Then
  Begin
    FName := SaveDialog1.FileName;
    DataModule2.IBTable1File1.SaveToFile(FName);
  End;
End;


Но это очень не удобно - сохранять а потом запускать... не могу никак придумать, что делать

Автор: former 22.9.2009, 09:55
Цитата(Gella7 @  22.9.2009,  09:47 Найти цитируемый пост)
Я пока только сделала пересохранение, тоесть берем файл и сохраняем с соответствующим расширением

Gella7, т.е. расширение ты знаешь. Вот по расширению и определяй с помощью какой программы открывать. Можно даже хранить в настройках ассоциации с определенными программами.

http://forum.vingrad.ru/forum/topic-38246.html пример загрузки из blob без сохранения на диск.
Однако, необходимо помнить, что в этом случае все загруженные данные будут висеть в памяти. Учитывая, что размеры некоторых PDF и DjVu файлов могут быть 50 - 70 Mb:
Цитата(Akella @  21.9.2009,  14:05 Найти цитируемый пост)
пожалей пользователей  smile 


ИМХО: Лучше файлы хранить отдельно, а в БД хранить ссылки на них или только их имена.

Автор: Gella7 22.9.2009, 10:23
Цитата

ИМХО: Лучше файлы хранить отдельно, а в БД хранить ссылки на них или только их имена.


Висеть то, это да... smile  
Я об этом думала, но имена файлов наверняка могут быть одинаковыми. Как то их пометить что-ли какими-нибудь индексами...
Да и все равно, как их запускать-то программно - они ведь все разные, и суть проблемы не меняется.


Цитата

Gella7, т.е. расширение ты знаешь. Вот по расширению и определяй с помощью какой программы открывать. Можно даже хранить в настройках ассоциации с определенными программами.


Я так понимаю, надо будет к каждому приложению код писать для открытия... ну это ладно.
я просто не знаю как. Если с word, excel или текстовый я как-то еще разберусь, например ворд

Код

Wrd:=CreateOleObject('Word.Application');

и так далее.

или это просто сделать? 

Автор: former 22.9.2009, 10:27
Цитата(Gella7 @  22.9.2009,  10:23 Найти цитируемый пост)
Я об этом думала, но имена файлов наверняка могут быть одинаковыми. Как то их пометить что-ли какими-нибудь индексами...

Присваивай уникальное имя при внесении в БД (переименовывай, переноси в хранилище - отдельную папку).
Цитата(Gella7 @  22.9.2009,  10:23 Найти цитируемый пост)
Да и все равно, как их запускать-то программно - они ведь все разные, и суть проблемы не меняется.

Цитата(Gella7 @  22.9.2009,  10:23 Найти цитируемый пост)
Я так понимаю, надо будет к каждому приложению код писать для открытия... ну это ладно.
я просто не знаю как. Если с word, excel или текстовый я как-то еще разберусь, например ворд

Используй ShellExecute. Другими словами, у тебя файлы будут открываться программами, с которыми ассоциировано то, или иное расширение в Windows. Храни расширение отдельным столбцом.

Автор: Gella7 22.9.2009, 10:29
Ну вот как? Лежит допустим какой-нибудь файл с *.ххх расширением, как его взять и запустить программно, независимо от расширения?
Не могу никак докопаться  smile

Добавлено через 1 минуту и 41 секунду
О, значит есть такое... пошла копать

Автор: former 22.9.2009, 10:32
Цитата(Gella7 @  22.9.2009,  10:29 Найти цитируемый пост)
Ну вот как? Лежит допустим какой-нибудь файл с *.ххх расширением, как его взять и запустить программно, независимо от расширения?

Читай про ShellExecute.

Автор: Gella7 22.9.2009, 11:34
Тот вариант, над которым я изначально работала, кажится все-таки в топку летит

потому что не могу в эту прекрасную функцию 

Код

ShellExecute (Form1.Handle, nil, 'C:\Nest\nest.djvu', nil, nil, SW_RESTORE);


засунуть этот файл из blob, потому что не могу его от туда вытащить вот так как-то...


вариант 
Цитата

ИМХО: Лучше файлы хранить отдельно, а в БД хранить ссылки на них или только их имена.


пользователь хочет прицепить файл. Показывает через OpenDialog хде он там у него
файл программно копируется на сервер, при этом запоминается имя, расширение... ну наверное к имени номер его прикрепляется.

Пользователь хочет открыть документ - ShellExecute и все.

и третий извращенный
сохраняется он все-таки в blob. 

а достается так - в зависимости от расширения создается пустой файл 
туда за писывается из blob

Код

  FName := 'ttt.txt';
  DataModule2.IBTable1File1.SaveToFile(FName);


открывается через ShellExecute
потом когда пользователь его закрывает, этот временный файлик удаляется (тоже поди не сложно)


по моему я переработала  smile 



Автор: Keeper89 22.9.2009, 11:45
Вариант 1
Вариант former'а с внешним хранением файлов мне нравится, и это можно попробовать реализовать как копирование файлов на сервер с добавлением получившего местоположения в БД.

Вариант 2
1) Загружаем файл в BLOB и записываем расширение.
2) При выборе - создаем временный файл из BLOB'а и открываем ShellExecute, а после закрытия удаляем.

Автор: dvamaster 22.9.2009, 13:31
мдя, а вот как запустив через shellexecute отследить закрытие запущеной программы?

Поэтому поводу из MSDN

Цитата

The return value is cast as an HINSTANCE for backward compatibility with 16-bit Windows applications. It is not a true HINSTANCE, however. The only thing that can be done with the returned HINSTANCE is to cast it to an int and compare it with the value 32 or one of the error codes below.


возвращаемый результат не HINSTANCE, а код ошибки

Автор: former 22.9.2009, 16:29
Цитата(Keeper89 @  22.9.2009,  11:45 Найти цитируемый пост)
2) При выборе - создаем временный файл из BLOB'а и открываем ShellExecute, а после закрытия удаляем. 

Цитата(dvamaster @  22.9.2009,  13:31 Найти цитируемый пост)
мдя, а вот как запустив через shellexecute отследить закрытие запущеной программы?

Необходимо еще учитывать то, что клиентская программа может быть закрыта раньше, viewer-а.
Года 4-е назад делал электронную библиотеку. Файлы хранил отдельно. Экземпляр файла копировал в Temp-папку на клиенте. При запуске клиента и выходе из него очищал временную папку.

Хранить файлы отдельно считаю лучше, т.к.:
- скорость в работе с БД;
- переносимость БД;
- малые затраты на резервное копирование.

Позже хотел сделать собственный viewer (что бы файлы не копировали), но так руки и не дошли.
Конечно это не панацея.

P.S. Точно сказать не могу, но вроде есть способ узнать, каким приложением файл открыт.

Автор: Akella 22.9.2009, 16:50
Не знаю, отвечали здесь или нет


Цитата(Gella7 @  22.9.2009,  09:47 Найти цитируемый пост)
Нужно сделать так, чтобы, допустим при щелчке на кнопку (не важно) файл открывался в соответствующем ему приложении.

Сохраняешь файл во временную папку с правильным расширением. А затем ShellExecute()

Автор: former 22.9.2009, 16:55
Akella, чуть http://forum.vingrad.ru/forum/topic-273743/kw-blob-%D1%84%D0%B0%D0%B9%D0%BB.html#.  smile  Только кэш на компе у клиента очищать.

Автор: Gella7 23.9.2009, 04:32
К слову, вдруг кому понадобится

создание каталога

Код

CreateDir('C:\Nest\\Test');


удаление каталога со всем содержимым

Код

function TForm1.DelDir(dir: string): Boolean;
var
fos: TSHFileOpStruct;
begin

ZeroMemory(@fos, SizeOf(fos));
with fos do
begin
wFunc := FO_DELETE;
fFlags := FOF_SILENT or FOF_NOCONFIRMATION;
pFrom := PChar(dir + #0);
end;
Result := (0 = ShFileOperation(fos));
End;


Это ко второму способу.

Всем большое спасибо!!! smile 

Автор: Gella7 23.9.2009, 07:59
Может кто-нибудь подскажет что тут не так:

Код

DataModule2.IBQuery1.SQL.Clear;
DataModule2.IBQuery1.sql.text:='INSERT INTO NEST1 (file1) VALUES (:F)';
DataModule2.IBQuery1.params.parseSQL(DataModule2.IBQuery1.sql.text, true);
DataModule2.IBQuery1.ParamByName('F').LoadFromFile('C:\Nest\nest.djvu');
DataModule2.IBQuery1.execsql;


ругается на предпоследнюю строчку и говорит что

not enough actual parameters

Автор: Frees 23.9.2009, 08:19
Цитата(Gella7 @  23.9.2009,  07:32 Найти цитируемый пост)
создание каталога

лучше наверно ForceDirectories()

тк CreateDir требует что бы путь по которому создаешь папку существовал

Добавлено через 2 минуты и 33 секунды
Код

DataModule2.IBQuery1.ParamByName('F').LoadFromFile('C:\Nest\nest.djvu', ftBlob);

Автор: Gella7 23.9.2009, 08:36
вроде так и должно быть....

Код

DataModule2.IBQuery1.ParamByName('F').LoadFromFile('C:\Nest\nest.djvu', ftBlob);


а он говорит что ftBlob неизвестный идентификатор

Автор: Akella 23.9.2009, 09:15
Gella7,  smile при чём здесь работа с блоб и создание каталогов????

Автор: former 23.9.2009, 09:32
Цитата(Gella7 @  23.9.2009,  08:36 Найти цитируемый пост)
а он говорит что ftBlob неизвестный идентификатор 

А модуль DB подключен?

Автор: Gella7 23.9.2009, 10:06
О, спасибо former,  модуль подключила ругаться перестал. Вроде все работает!!!


Akella, поймешь если выше перечитаешь вариант №2 создание временных файлов чтоб кидать туда файлы из blob

Еще раз всем спасибо!!!

Автор: former 23.9.2009, 10:20
Цитата(Gella7 @  23.9.2009,  10:06 Найти цитируемый пост)
Еще раз всем спасибо!!! 

Gella7, тогда внизу поставь галочку, что вопрос решен.

Автор: Gella7 23.9.2009, 10:32
Еще не решен   smile 

теперь не могу вытащить файл от туда.

с таблицами было 

Код

DataModule2.IBTable1File1.SaveToFile(FName);


все работало.

Код

DataModule2.IBQuery1['file1'].Value.SaveToFile(FName, ftblob);

не хочет никак... говорит "invalid variant operation"

Добавлено через 6 минут и 36 секунд
Все!

вот так сделала

Код

TBlobField(DataModule2.IBQuery1.FieldByName('file1')).SaveToFile(FName);

Автор: former 23.9.2009, 10:44
Цитата(Gella7 @  23.9.2009,  10:32 Найти цитируемый пост)
теперь не могу вытащить файл от туда.

Эту http://forum.vingrad.ru/forum/topic-38246.html почитай.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)