delphi XE中如何读取文件内容为字符串

问题描述 投票:0回答:4

我正在将应用程序从 delphi 2007 迁移到 delphi xe,但在读取 ascii 文件并将内容存储在字符串中的过程中遇到问题。

此代码在 Delphi 2007 中有效

function LoadFileToStr(const FileName: TFileName): String;
var
  FileStream : TFileStream;
begin
  FileStream:= TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
    try
     if FileStream.Size>0 then
     begin
      SetLength(Result, FileStream.Size);
      FileStream.Read(Pointer(Result)^, FileStream.Size);
     end;
    finally
     FileStream.Free;
    end;
end;

但是当我在 Delphi XE 中执行这段代码时,结果只是像“?????????”这样的符号。我知道 Delphi XE 是 unicode 所以我改变了这些行

      SetLength(Result, FileStream.Size);
      FileStream.Read(Pointer(Result)^, FileStream.Size);

      SetLength(Result, FileStream.Size*2);
      FileStream.Read(Pointer(Result)^, FileStream.Size);

将文件内容存储在unicode字符串中,但结果是相同的。

如何修复此过程以读取该文件的内容?

delphi encoding delphi-xe delphi-2007
4个回答
31
投票

您的代码不起作用,因为您正在使用 unicode 字符串作为缓冲区读取文件的内容,因此您只是将字节从 TFileStream 的内部缓冲区移动到 unicode 字符串,忽略编码。

您可以轻松修复您的程序,只需将结果类型更改为

AnsiString

function LoadFileToStr(const FileName: TFileName): AnsiString;

但我会建议您使用

TFile.ReadAllText
函数,而不是在一行代码中读取文件的内容并处理文件的编码。


23
投票

您可以使用 ReadAllText 函数通过一行代码来实现这一点。像这样:

Uses IOUtils;

TFile.ReadAllText(FileName);

TFile.ReadAllText(FileName, s, TEncoding.ASCII) // if you want to force ASCII (other) encoding 

它将正确检测 ANSI、Unicode 和二进制文件。


12
投票

您应该考虑编码,例如:

function LoadFileToStr(const FileName: TFileName): String;
var
  FileStream : TFileStream;
  Bytes: TBytes;

begin
  Result:= '';
  FileStream:= TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  try
    if FileStream.Size>0 then begin
      SetLength(Bytes, FileStream.Size);
      FileStream.Read(Bytes[0], FileStream.Size);
    end;
    Result:= TEncoding.ASCII.GetString(Bytes);
  finally
    FileStream.Free;
  end;
end;


//test
procedure TForm2.Button1Click(Sender: TObject);
begin
  ShowMessage(LoadFileToStr('C:\autoexec.bat'));
end;

6
投票

我建议使用TStringList来加载文件的内容,然后将结果设置为variable.Text,例如:

function LoadFileToStr(const FileName: TFileName): String;  
var LStrings: TStringList;  
begin  
    LStrings := TStringList.Create;
    try  
      LStrings.Loadfromfile(FileName);  
      Result := LStrings.text;  
    finally  
      FreeAndNil(LStrings);  
    end;  
end;

这样你就不用担心任何事情,恕我直言,它将向后和未来兼容。

编辑:如果您需要从 TStream 后代加载,请将 LoadFromFile 替换为 LoadFromStream。

© www.soinside.com 2019 - 2024. All rights reserved.