【发布时间】:2021-06-16 18:29:45
【问题描述】:
我有一些第三方代码使用以下代码一次写入日志文件一行:
procedure TLog.WriteToLog(Entry: ansistring);
var
strFile: string;
fStream: TFileStream;
strDT: ansistring;
begin
if ((strLogDirectory<>'') and (strFileRoot<>'')) then
begin
if not(DirectoryExists(strLogDirectory)) then
ForceDirectories(strLogDirectory);
strFile:=strLogDirectory + '\' + strFileRoot + '-' + strFilename;
if FileExists(strFile) then
fStream:=TFileStream.Create(strFile, fmOpenReadWrite)
else
fStream:=TFileStream.Create(strFile, fmCreate);
fStream.Seek(0, soEnd);
if blnUseTimeStamp then
strDT:=formatdatetime(strDateFmt + ' hh:mm:ss', Now) + ' ' + Entry + chr(13) + chr(10)
else
strDT:=Entry + chr(13) + chr(10);
fStream.WriteBuffer(strDT[1], length(strDT));
FreeandNil(fStream);
end;
end;
这以前在客户站点上运行良好,但在过去几周中,它现在在标题中出现错误。
没有其他进程应该打开文件。我怀疑它是防病毒软件,但客户声称他们已禁用防病毒软件,但仍然收到错误消息。
该错误似乎只发生在代码处于循环中并快速写入行时。
我想知道的: 假设不是防病毒软件(或类似软件)导致问题,是否是由于操作系统在下次尝试写入文件之前未清除标志(或类似软件)?
【问题讨论】:
-
您缺少
TFileStream构造函数(即fmShareDenyNone等)的共享权限,您还应该使用try..finally保护TFileStream。在ForceDirectories()之前不需要DirectoryExists(),它会在内部检查是否存在。 -
IIRC,如果文件不存在,
fmOpenReadWrite不会创建文件吗?我得检查一下…… -
通常不会,但除了 AV 之外,可能还有其他扫描进程试图访问您的文件。其次,当某行写入失败时,正如雷米所说,您不会释放文件流并保持文件锁定。
-
@Toby 是的,这很重要,这就是我之前提到
fmShareDenyNone的原因。例如:fStream := TFileStream.Create(strFile, fmOpenReadWrite or fmShareDenyNone);“我问这是否可能是因为它经常快速地打开和关闭文件” - 不,这不是问题。该文件还有另一个打开的句柄,并且该句柄指定的共享权限(未指定)与此TFileStream请求的权限不匹配。使用SysInternals Process Explorer 之类的工具进行验证。 -
@Toby 是的,确实如此:“
Mode参数由一个开放模式和(可能)一个共享模式或'ed 在一起组成。。 i>"
标签: windows delphi delphi-10.2-tokyo