以下示例我正在计算.dfm文件中的行数,并且计数错误,因为.dfm以二进制格式保存。
如果我打开.dfm文件并右键单击并将文本dfm设置为选中并且计数正确。以下是代码
function TForm1.FindNumberOfLinesInFile(FileName: String): Integer;
var
contents : TStringList;
filestream : TFileStream;
outStream : TMemoryStream;
begin
try
try
Result := 0;
contents := TStringList.Create;
if edtFileToSearch.Text = '.dfm' then
begin
contents.LoadFromFile(FileName);
//i am binary
if pos('OBJECT', Uppercase(contents[0])) = 0 then // Count is coming wrong with this
begin
contents.Clear;
fileStream := TFileStream.Create(FileName, fmShareDenyNone);
outStream := TMemoryStream.Create;
try
ObjectResourceToText(filestream,outStream);
outStream.Position := 0;
Contents.LoadFromStream(outStream);
finally
FreeAndNil(outStream);
end;
end
else
begin
fileStream := TFileStream.Create(FileName, fmShareDenyNone);
Contents.LoadFromStream(fileStream);
end;
end
else
begin
fileStream := TFileStream.Create(FileName, fmShareDenyNone);
Contents.LoadFromStream(filestream);
end;
Result := contents.Count;
finally
FreeAndNil(fileStream);
FreeAndNil(contents);
end;
except
on e: Exception do Result := -1;
end;
end;
我有两个问题
1)如何设置文本dfm值以检查所有dfm文件(我有大约1000个dfm文件)?
2)如何正确加载二进制文件并计算行数?
答案 0 :(得分:2)
Delphi附带了一个命令行工具,名为convert
。打开命令提示符并确保您的Delphi bin目录位于PATH
中。然后输入:
C:\projects\myprocject> convert
输出将是这样的:
Delphi Form Conversion Utility Version 5.0 Copyright (c) 1995,99 Inprise Corporation Usage: convert.exe [-i] [-s] [-t | -b] -i Convert files in-place (output overwrites input) -s Recurse subdirectories -t Convert to text -b Convert to binary
所以,你应该能写:
C:\projects\myprocject> convert -i -s -t *.dfm
实现所需的更改。
答案 1 :(得分:0)
David的回答解决了您的第一个问题:您可以使用Delphi提供的命令行工具将所有现有的二进制DFM转换为文本。
除了解决您的直接问题之外,还强烈建议这样做,因为它可以更容易(即可能!)在版本控制中直观地改变您的DFM文件。
至于第二部分,如果由于某种原因你仍想要或者需要在你的代码中处理二进制DFM文件,那就是使用 TestStreamFormat()函数来确定一个流是否是一个有效的资源流,无论是二进制还是文本格式,只有在需要时才调用 ObjectResourceToText()函数。
这个辅助函数将指定文件名(DFM)的内容返回到提供的 TStrings (例如 TStringlist ),演示了这一点并可能为您简化:
procedure GetDfmIntoStrings(aFilename: String; aStrings: TStrings);
var
istrm, ostrm: TStream;
begin
ostrm := NIL;
istrm := TFileStream.Create(aFilename, fmOpenRead or fmShareDenyNone);
try
case TestStreamFormat(istrm) of
sofBinary : begin
ostrm := TStringStream.Create('');
ObjectResourceToText(istrm, ostrm)
end;
sofText : ostrm := istrm;
else
raise EFilerError.Create(aFilename + ' is not a valid resource stream (DFM)');
end;
ostrm.Position := 0;
aStrings.LoadFromStream(ostrm);
finally
if ostrm <> istrm then
ostrm.Free;
istrm.Free;
end;
end;