要检查数据库(sql Anywhere)何时被激发并准备好接收请求,我将数据库消息窗口输出到日志(文本)文件,然后尝试使用LoadStringFromFile读取它,然后我使用LoadStringFromFile搜索特定文本波什.问题是,当文件正在使用时,这会失败(我假设).
Exec(strInstallPath + '\Bin32\dbeng17.exe','-n ' + strEngineName + ' "' + strInstallPath + '\Database\Olympus.db" -n ' + strDatabaseName + ' -gdall -xtcpip -ti0 -c25p -ot "' + strTempPath + '\dbeng.log"','',SW_HIDE,ewNoWait,intResultCode); if not LoadStringFromFile(strTempPath + '\dbeng.log',astrDatabaseEngineLog) then begin Log('Loading string from file Failed.'); end;
我还尝试使用FileCopy复制日志文件并尝试从文件的副本读取,但FileCopy也失败.
if not FileCopy(strTempPath + '\dbeng.log',strTempPath + '\dbengcopy.log',False) then begin Log('File copy Failed.'); end;
有没有办法从正在使用的文件或其他方式读取?
解决方法
使用TFileStream.Create(FileName,fmOpenRead或fmShareDenyNone).
在Inno Setup的Unicode版本中,由于类的接口不良,它的使用很棘手.
function BufferToAnsi(const Buffer: string): AnsiString; var W: Word; I: Integer; begin SetLength(Result,Length(Buffer) * 2); for I := 1 to Length(Buffer) do begin W := Ord(Buffer[I]); Result[(I * 2)] := Chr(W shr 8); { high byte } Result[(I * 2) - 1] := Chr(Byte(W)); { low byte } end; end; function LoadStringFromLockedFile(const FileName: string; var S: AnsiString): Boolean; var Buffer: string; Stream: TFileStream; begin Result := True; try Stream := TFileStream.Create(FileName,fmOpenRead or fmShareDenyNone); try SetLength(Buffer,Stream.Size div 2); Stream.ReadBuffer(Buffer,Stream.Size); S := BufferToAnsi(Buffer); finally Stream.Free; end; except Result := False; end; end;
该代码基于TLama’s code发布于TLama’s code.