怎样处理临时文件?(60分)

  • 主题发起人 主题发起人 DiamondKing
  • 开始时间 开始时间
D

DiamondKing

Unregistered / Unconfirmed
GUEST, unregistred user!
表中有一Blob字段存储着一些文件(各种类型,.exe,.bmp,.ico,.doc......),现在需要将它们
取出来,进行一些必要的操作,如显示它的图标,如果是.exe就执行它....,就象处理邮件中的附件一样.
这样是否先要将文件储存到windows临时目录下,如何获取windows临时目录的路径,
临时目录中的数据会自动清除吗?
 
你可以创建临时文件来处理, 参见下面的代码, 应用程序将自己复制到临时文件
然后删除自己了.

program DelMe;

{$APPTYPE CONSOLE}

uses
Windows, SysUtils;
var //
szSrc, //
szDest : array[0..MAX_PATH] of char; //
szCmdLine : string;
hFile : THandle;
hProcess : THandle;
SI : TStartupInfo;
PI : TProcessInformation;
nTimes : DWord;
begin
if ParamCount = 0 then
begin
GetModuleFileName(0, szSrc, MAX_PATH);
GetTempPath(MAX_PATH, szDest);
GetTempFileName(szDest, 'Tmp', 0, szDest);
CopyFile(szSrc, szDest, FALSE); // 将当前可执行文件复制一个副本

hFile := CreateFile(szDest, // pointer to name of the file
0, // access (read-write) mode
FILE_SHARE_READ, // share mode
nil, // pointer to security attributes
OPEN_EXISTING, // how to create
FILE_FLAG_DELETE_ON_CLOSE, // file attributes
0); // handle to file with attributes to copy

hProcess := OpenProcess(SYNCHRONIZE, // access flag
TRUE, // handle inheritance flag
GetCurrentProcessId); // process identifier


szCmdLine := Format('%s %d "%s"', [szDest, hProcess, szSrc]); //格式化命令行参数

FillChar(SI, SizeOf(SI), 0);
SI.cb := SizeOf(SI);

CreateProcess(nil, // pointer to name of executable module
PChar(szCmdLine), // pointer to command line string
nil, // pointer to process security attributes
nil, // pointer to thread security attributes
TRUE, // handle inheritance flag
0, // creation flags
nil, // pointer to new environment block
nil, // pointer to current directory name
SI, // pointer to STARTUPINFO
PI); // pointer to PROCESS_INFORMATION

CloseHandle(hProcess);
CloseHandle(hFile);
end
else
begin
hProcess := THANDLE(StrToInt(ParamStr(1)));
WaitForSingleObject(hProcess, INFINITE); //等待主进程结束
CloseHandle(hProcess);

DeleteFile(ParamStr(2));
end;
end.
 
//得到一个唯一的临时文件名,参数strPath如果为''的话,自动得到windows的临时
//文件目录.strPrefix为临时文件后缀.
function CreateTempFile(strPath,strPrefix : string): string;
var
size : integer;
szTempFile : PChar;
strTempPath : string;
begin
size := MAX_PATH;
GetMem(szTempFile, size);
if strTempPath = '' then strTempPath := GetWinTempPath
else strTempPath := strPath;
GetTempFileName(PChar(strTempPath),strPrefix,0,szTempFile);
result := szTempFile;
FreeMem(szTempFile);
end;

//得到windows的临时文件目录
function GetWinTempPath: string;
var
size : integer;
szPath : PChar;
begin
size := MAX_PATH;
GetMem(szPath, size);
GetTempPath(size, szPath);
result := szPath;
FreeMem(szPath);
end;
 
楼上的两位都说了,我就不费口舌了。
 
tseug,Celestial dog:非常感谢!
我必须先从Blob字段中读取文件流,然后将这个流文件写到临时目录下(假设已经获得目录),
用户使用完毕,或者是关闭程序,临时目录下的文件自动删除. 如果Celestial dog能多一个函数,
象tseug的那样等待进程结束删除临时目录的文件就妙了

我先调试一下.
 
Celestial dog:
function CreateTempFile 中
--------------------------------------
if strTempPath = '' then strTempPath := GetWinTempPath
else strTempPath := strPath;
--------------------------------------
是否是if strPath='' then..... 否则strTempPath:总是等于GetTempPath. strPath就没有作用.
还有这个函数到底怎么工作的,传入的参数strPath,strPrefix 到底是指什么?
文件名,以及它的后缀名?
是否这样: 假设我有个文件名diamondking.doc 调用CreateTempFile('DiamondKing','doc')
则返回 XXXXX.tmp 是这样吗?



 
1、你可以自己设strPath,那她就不为空
2、strPath是指你设的路径
strPrefix是指它的后缀名
譬如你blob里的文件是fname.bmp:
首先,取临时文件目录,YourPath:=GetWinTempPath;
然后,得到临时文件名,YourFileName:=CreateTempFile(YourPath,'bmp' : string);
得到的临时文件名为 *.bmp

注:这两个函数是别人写的,上面的观点如有不妥,请大虾指正,我只是用过webbrowser通过
临时文件从blob里取word文档~~
 
Celestial dog: 因为没有操作过临时文件,所以还是麻烦讲一下整个过程.
不知道是否这样:以一个word文档为例
1.从Blob读取word文档,获取其文件名
2.由GetWinTempPath得到临时目录,通过CreateTempFile(临时目录,文件名)得到一个
唯一的临时文件名
3.讲读取的文件流存储到该临时文件名 !! ????
然后再进行别的操作如打开,获取图标等. 是这样吗?急等答复!!或者你把使用webBrowser
的过程讲以下! 谢谢!
 
是这样的
if WebBrowser1.LocationURL <> 'about:blank'
then begin
showmessage('请先清空文档!');
abort;
end;
Fpath:=GetWinTempPath;
Fname:=CreateTempFile(Fpath,'doc');
bbl.SaveToFile(Fname);
WebBrowser1.Navigate(Fname);
 
明白了!
不过你的
function CreateTempFile
if strTempPath = '' then strTempPath := GetWinTempPath
else strTempPath := strPath;
--------------
if StrTempPath='' ........应该改为if StrPath =''
它的本意可能是如果传入的StrPath为空则StrTempPath取GetWindTempPath ,否则取StrPath.

谢谢!


 
多人接受答案了。
 

Celestial dog:求证一下.
我查了一下GetTempFileName的原型
在function CreateTempFile 中由这条语句
GetTempFileName(PChar(strTempPath),strPrefix,0,szTempFile);
但是输入参数strPrefix是string ,而这里必须接受一个PChar型(以'/0'结尾的字符串),
所以它的正确写法是GetTempFileName(PChar(strTempPath),PChar(strPreFix),0,szTempFile);
不然无法工作!!
GetTempFileName() 接受的第二个参数 ,你可以查一下MSDN
UINT GetTempFileName(
LPCTSTR lpPathName, // pointer to directory name for temporary
// file
LPCTSTR lpPrefixString, // pointer to filename prefix
UINT uUnique, // number used to create temporary filename
LPTSTR lpTempFileName
// pointer to buffer that receives the new
// filename
-----------------------
LPCTSTR: 是文件名的前缀.
CreateTempFile 不管你给什么样的输入参数,它的输出形式都是 path/preuuuu.tmp
肯定不会得到你所说的 *.bmp这种形式.
不知道你测试过没有? 不过做点小的处理就可以解决.





 
1.正确写法是GetTempFileName(PChar(strTempPath),PChar(strPreFix),0,szTempFile);
我的程序里也是这样写的,原来的函数是有点问题(忘了告诉你)
2.后缀名我没试过,你一切搞定后,希望能把原码给我一份,我学习一下,先谢了
 
1.那个函数不是有点问题,而是很多,你用它处理word文档,它生成的是.tmp而不是你需要的
.doc或者.txt ,你怎么显示它呢?一堆乱码??
2 这里用后缀名也是可以的,用GetTempFileName 总是可以生成一个唯一的临时文件名,
----
如果你想将你的文件存储到临时文件并且文件名唯一,并且后缀名为原文件的后缀名(比如
.doc存入后同样可以显示它,获取其图标),试试这个.
{*******************************************************************}
FileName 为文件名(如 DDD.txt)
function GetUniqueTempFileName(FileName:string): string;
var
WFileName,CFileName,ECFileName:string;
PrefixFileName,PostfixFileName:string;
begin
//取原文件的前缀
PrefixFileName:=Copy(FileName,1,Pos('.',FileName)-1);
//取原文件的后缀
PostfixFileName:=Copy(Filename,pos('.',FileName)+1,Length(FileName)-pos('.',FileName));
//得到一个唯一的临时文件名+路径,并删除这个创建的临时文件
CFileName:=CreateTempFile(GetWinTempPath,PrefixFileName);
DeleteFile(CFileName);//删除这个创建的临时文件
//提取这个临时文件名
ECFileName:=ExtractFileName(CFileName);
//获取临时文件的前缀
WFilename:=Copy(ECFileName,1,Pos('.',ECFileName)-1);
//返回 需要格式的文件名=临时路径+临时文件的前缀+'.'+原文件的后缀 ,
Result:=GetWinTempPath+Trim(WFileName)+'.'+Trim(PostfixFileName);
end;
{*******************************************************************}
这个函数要用到你所提供的两个函数(必须试修改过的)
不知道你的程序是否可以获得原文件名,如果不可以你的输入参数就可以这么写
GetUniqueTempFileName('xxx.doc'); 只要保证后缀名为.doc(word文档) 就好了.
或者你改写一下函数到你满意为止.
有问题请回复.

 
后缀名对用webbrowser.navigate一点影响都没有,对此我想可能是这样的,虽然生成的临时
文件是以.tmp未后缀,但是她保留了原文档的一些特性,譬如,把word文档存进blob后,用
olecontainer调出,然后激活ole,看到的是word文档形式
多联系:jiangsu_hy@21cn.com
 
o !
我就不行了.如果不将后缀名转换到象原文件那样,我就无法得到图标,或者是让它执行.
点我的名字可以看到email.
 
后退
顶部