Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

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


Zzzz ©   (2009-10-23 22:06:00) 

Задача - считать содержимое 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 меняет заголовок на тот, в кот. находится сама программа. Изображение так и не появляется. В чем может быть дело?


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

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


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


> Zzzz   (24.10.09 14:08) [5]


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


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

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


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

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

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


Loginov Dmitry   (2009-10-24 14:44:00) [5]

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


Кстати 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 :)


Palladin   (2009-10-24 14:26:00) [6]


> 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:18:00) [7]

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


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


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


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

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


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


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


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


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

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


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


Zzzz   (2009-10-23 23:29:00) [11]


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

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


Loginov Dmitry   (2009-10-23 23:04:00) [12]

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


Наверх

Титульная страница Поиск, карта сайта Написать письмо