Ste*_*cki 4 delphi temporary-files
在我的应用程序中,我的用户可以将文件(pdf/xls/doc)导入表或将它们导出到文件夹.现在我想直接打开这些文件.
到目前为止,我能够: - 获得一个唯一的名称 - 将blob文件保存到生成的文件中 - 打开它
问题是我不知道如何删除(或更新)文件,之后用户将关闭该文件.
如果有人可以帮助我,我会很高兴:)
这是我的代码的快照:
procedure OpenTemporaryFile(AFileExtension: String; AKey: Integer;
AMyConnection: TMyConnection);
Var
qrDocuments : TMyQuery ;
TmpName,ExtName: string;
TempFileName: TFileStream;
begin
//Generate an unique tmp file located into user temp folder
TmpName:= FileGetTempName('~SI');
ExtName:= ChangeFileExt(TmpName, AFileExtension);
//Change files extension so that Shellexecute will be able to open the file
RenameFile(TmpName,ExtName );
//Creating the FileStream (data is fetched from an blob field)
TempFileName := TFileStream.Create(ExtName, fmOpenReadWrite );
qrDocuments := TMyQuery.create(nil);
try
qrDocuments.Connection := AMyConnection;
qrDocuments.Close;
qrDocuments.SQL.Clear;
qrDocuments.SQL.Text:='Select Id,FileName,Data from files where Id = :prId And Data IS NOT NULL';
qrDocuments.ParamByName('prId').AsInteger := AKey;
qrDocuments.open;
TBlobField(qrDocuments.FieldByName('Data')).SaveToStream(TempFileName);
finally
TempFileName.Free;
qrDocuments.free;
end;
ShellExecute(Application.Handle, 'open', Pchar(ExtName), '', '', SW_SHOWNORMAL);
DeleteFile( ExtName);
end;
Run Code Online (Sandbox Code Playgroud)
不幸的是,Remy Lebeau现在有4个赞成此答案,当时该技术根本不适用于大多数应用程序.也许其中一位赞助商可以发布一个代码片段,允许用Acrobat Reader打开PDF文件,而文件仍然打开带有FILE_FLAG_DELETE_ON_CLOSE标志?
无论如何,您可以在这里结合一些提示以获得最佳结果:
我更喜欢这种方法在重启时注册所有文件以便删除,因为我不确定你的应用程序可能会打开多少个临时文件 - 也许可以注册的文件数量有限制MOVEFILE_DELAY_UNTIL_REBOOT?这是一个系统范围的资源,我只会谨慎使用.
一种可能性是将每个临时文件添加到系统启动期间删除的文件列表中.
在Windows NT平台上(从Windows 2000开始),您只需调用MoveFileEx函数,并将第二个参数(destination)设置为nil并使用标志MOVEFILE_DELAY_UNTIL_REBOOT.
在Windows 9x上,这要复杂得多.您必须编辑文件%WINDIR%\ wininit.ini并在[重命名]部分中写入一个条目.
MSDN条目如何移动当前正在使用的文件描述了这两种技术.
函数DSiMoveOnReboot(免费DSiWin32库的一部分)处理两个操作系统.如果传递空字符串作为第二个参数,它将在重新引导时删除源文件.
function DSiMoveOnReboot(const srcName, destName: string): boolean;
var
wfile: string;
winit: text;
wline: string;
cont : TStringList;
i : integer;
found: boolean;
dest : PChar;
begin
if destName = '' then
dest := nil
else
dest := PChar(destName);
if DSiIsWinNT then
Result := MoveFileEx(PChar(srcName), dest, MOVEFILE_DELAY_UNTIL_REBOOT)
else
Result := false;
if not Result then begin
// not NT, write a Rename entry to WININIT.INI
wfile := DSiGetWindowsFolder+'\wininit.ini';
if FileOpenSafe(wfile,winit,500,120{one minute}) then begin
try
cont := TStringList.Create;
try
Reset(winit);
while not Eof(winit) do begin
Readln(winit,wline);
cont.Add(wline);
end; //while
if destName = '' then
wline := 'NUL='+srcName
else
wline := destName+'='+srcName;
found := false;
for i := 0 to cont.Count - 1 do begin
if UpperCase(cont[i]) = '[RENAME]' then begin
cont.Insert(i+1,wline);
found := true;
break;
end;
end; //for
if not found then begin
cont.Add('[Rename]');
cont.Add(wline);
end;
Rewrite(winit);
for i := 0 to cont.Count - 1 do
Writeln(winit,cont[i]);
Result := true;
finally cont.Free; end;
finally Close(winit); end;
end;
end;
end; { DSiMoveOnReboot }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4024 次 |
| 最近记录: |