Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.12.13;
Скачать: CL | DM;

Вниз

открытие содерж. blob-поля во врем. файле   Найти похожие ветки 

 
Zzzz   (2009-10-23 22:06) [0]

Задача - считать содержимое blob-поля БД во временный файл и открыть его программой, кот. открывает файлы этого типа. Причем желательно, чтобы сам файл вообще не сбрасывался на диск - для этого я применяю комбинацию флагов FILE_ATTRIBUTE_TEMPORARY or FILE_FLAG_DELETE_ON_CLOSE. А как только ту программу закроют, файл удаляется.

var blob:TStream; f:file; s:string; i:integer; j:dword; buffer:array[0..2047] of byte; //в s - имя файла

blob:=adoDataset1.CreateBlobStream(adodataset1.Fields[0], bmRead);
blob.Seek(0, soFromBeginning);
f:=CreateFile(PChar(s), GENERIC_READ or
GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, CREATE_NEW,
FILE_ATTRIBUTE_TEMPORARY or FILE_FLAG_DELETE_ON_CLOSE, 0);

Далее я копирую в файл из blob с пом. writefile и запускаю:
repeat
i:=blob.Read(buffer,2048);
writefile(f,buffer,i,j,nil);
until j<2048;
blob.free;
ShellExecute(Handle, "open", pchar(s), nil, nil, SW_SHOW);

И в результате не открывается вообще ничего. Т. е. ACDSee запускается, и имя файла, кот. записано в s, видно в заголовке ACDSee примерно долю секунды, потом ACDSee меняет заголовок на тот, в кот. находится сама программа. Изображение так и не появляется. В чем может быть дело?


 
Loginov Dmitry ©   (2009-10-23 23:04) [1]

Фокусами Вы тут занимаетесь, имхо!
Если ACDSee, то сохраняйте файл по-нормальному, например
blob.SaveToFile
Если без сохранения в файл, то добавьте в своем приложении
окно с компонентом TImage, и в него загружайте изображение
(в некоторых случаях можно использовать TDBImage).


 
Zzzz   (2009-10-23 23:29) [2]


> Если ACDSee, то сохраняйте файл по-нормальному, например
> blob.SaveToFile

Пробовал, работало. Но надо тогда чтобы старые файлы удалялись. Только как это лучше сделать? Удалять все файлы в опред. папке при запуске программы? Просто хотелось чтобы ОС сама их удаляла и чтобы не заморачиваться с удалением самому.


 
Loginov Dmitry ©   (2009-10-23 23:36) [3]

> Но надо тогда чтобы старые файлы удалялись. Только как это
> лучше сделать? Удалять все файлы в опред. папке при запуске
> программы?


Неплохой вариант.


 
Сергей М. ©   (2009-10-23 23:53) [4]


> В чем может быть дело?


В том что система успевает удалить файл ДО того как ACDSee его откроет.


 
Zzzz   (2009-10-24 14:08) [5]


> В том что система успевает удалить файл ДО того как ACDSee
> его откроет.

Но он ведь должен удалятьcя после закрытия, а я его явно не закрываю, значит не должен удаляться?


 
Loginov Dmitry ©   (2009-10-24 14:18) [6]

> а я его явно не закрываю, значит не должен удаляться?


На самом делей Ваш код выполняет создание файла, и после этого
файл остается открытым в монопольном режиме. У ACDSee нет прав
на открытие данного файла. Изучите справку по функции CreateFile(),
возможно она позволяет выполнить создание нового файла без
монопольного доступа на чтение.


 
Palladin ©   (2009-10-24 14:26) [7]


> Zzzz   (24.10.09 14:08) [5]

ты мудришь чего то слишком...

1 заведи директорию для временных файлов
2 скидывай туда файлы и открывай
Var
f:TFileStream;
...
f:=TFileStream.Create(<random_file_name>,fmCreate);
Try
f.CopyFrom(blob,0);
Finally
f.free;
End;
ShellExecute(...)

3 при завершении приложения убивай временную директорию


 
Loginov Dmitry ©   (2009-10-24 14:44) [8]

> возможно она позволяет выполнить создание нового файла без
> монопольного доступа на чтение.


Кстати API позволяет. Непонятно, по какой причине TFileCtream.Create()
не учитывает флаги fmShareDenyXXX.

Из хэлпа:
ranges of bytes.
FILE_FLAG_DELETE_ON_CLOSE
Indicates that the operating system is to delete the file immediately after all of its handles have been closed, not just the handle for which you specified FILE_FLAG_DELETE_ON_CLOSE. Subsequent open requests for the file will fail, unless FILE_SHARE_DELETE is used.


Очень сомневаюсь, что ACDSee открывает файл с атрибутом FILE_SHARE_DELETE :)


 
Zzzz   (2009-10-24 15:48) [9]

Попробовал с флагом FILE_SHARE_DELETE, закрывая файл сразу после открытия ACDSee:
ShellExecute(Handle, "open", pchar(s), nil, nil, SW_SHOW);
fileclose(f);

Файл нормально открывается, но когда ACDSee закрываешь (вместе с самой программой), то файл так и остается на диске. Не удаляется.


 
Zzzz   (2009-10-24 15:55) [10]

Извиняюсь, перепутал. Я FILE_FLAG_DELETE_ON_CLOSE убирал, в потом забыл снова поставить. А ACDSee теперь говорит, что "Программа просмотра не обнаружила файл в системе".


 
Сергей М. ©   (2009-10-24 16:42) [11]


> Zzzz   (24.10.09 14:08) [5]


Полагаю, ты завершаешь работу своего приложения до того как созданный тобой файл будет открыт другим приложением.


 
Zzzz   (2009-10-24 17:21) [12]

Да нет, не завершаю. Вот убрал fileclose(f) (кот. в самом конце после ShellExecute), и теперь ACDSee пишет "Исходный формат данных не опознан".



Страницы: 1 вся ветка

Текущий архив: 2009.12.13;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.013 c
6-1210610534
Пробегал2...
2008-05-12 20:42
2009.12.13
UDP-сервер, принимающий пакеты по всем интерфейсам


15-1255811409
Юрий
2009-10-18 00:30
2009.12.13
С днем рождения ! 18 октября 2009 воскресенье


11-1169181906
AlexM
2007-01-19 07:45
2009.12.13
VCL и KOL


1-1228589526
Германн
2008-12-06 21:52
2009.12.13
BDE и bat-файлы


15-1255166733
TStas
2009-10-10 13:25
2009.12.13
Как работают подпрограммы?