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

Del*_*bie 10 delphi delphi-2007 delphi-xe

我正在将我的应用程序从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;
Run Code Online (Sandbox Code Playgroud)

但是当在delphi XE中执行此代码时,结果只是'????????'这样的符号,我知道哪个delphi xe是unicode所以我改变了这些行

      SetLength(Result, FileStream.Size);
      FileStream.Read(Pointer(Result)^, FileStream.Size);
Run Code Online (Sandbox Code Playgroud)

      SetLength(Result, FileStream.Size*2);
      FileStream.Read(Pointer(Result)^, FileStream.Size);
Run Code Online (Sandbox Code Playgroud)

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

how i can fix this procedure to read the content of this file?

RRU*_*RUZ 26

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

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

function LoadFileToStr(const FileName: TFileName): AnsiString;
Run Code Online (Sandbox Code Playgroud)

但我会建议你使用这个TFile.ReadAllText函数,而不是在一行代码中读取文件的内容,也处理文件的编码.


WeG*_*ars 13

您可以使用ReadAllText函数通过一行代码实现此目的.像这样:

Uses IOUtils;

TFile.ReadAllText(FileName);
TFile.ReadAllText(FileName, s, TEncoding.ASCII) // force encoding 
Run Code Online (Sandbox Code Playgroud)

它将正确检测ANSI,Unicode和二进制文件.(现在我看到RRuz已经推荐了相同的).


klu*_*udg 9

您应该考虑编码,例如:

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;
Run Code Online (Sandbox Code Playgroud)


Com*_*sNo 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;
Run Code Online (Sandbox Code Playgroud)

通过这种方式你不必担心任何事情,它将是向后和未来兼容恕我直言.

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