如何设置文本 dfm 值以检查所有 dfm files/Count .dfm 二进制文件中的行数

How to set text dfm value to checked on all dfm files/Count number of lines in .dfm binary file

在下面的示例中,我正在计算 .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;

我有2个问题

1)如何设置文本 dfm 值以检查所有 dfm 文件(我有大约 1000 个 dfm 文件)?

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

实现所需的更改。

David 的回答解决了您的第一个问题:您可以使用 Delphi 提供的命令行工具将所有现有的二进制 DFM 转换为文本。

除了解决您眼前的问题外,我们还强烈建议您这样做,因为这将使您更容易(即完全可能!)在版本控制中直观地比较 DFM 文件的更改。

至于第二部分,如果出于某种原因您仍然希望或需要在代码中处理二进制 DFM 文件,则使用 TestStreamFormat() 函数来确定是否stream 是一个有效的资源流,无论它是二进制还是文本格式,只有在需要时才调用 ObjectResourceToText() 函数。

此辅助函数 return 将(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;