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

发布于 2024-11-09 14:28:14 字数 931 浏览 4 评论 0原文

我正在将我的应用程序从 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 字符串中,但结果是相同的。

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

I'm migrating my application from delphi 2007 to delphi xe, but am having problems with a procedure which reads an ascii file and stores the content in a string.

This code worked in 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;

But when I execute this code in Delphi XE the result are just symbols like '????????'. I know that Delphi XE is unicode so I changed these lines

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

to

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

to store the content of the file in the unicode string but the result is the same.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

忆伤 2024-11-16 14:28:14

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

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

function LoadFileToStr(const FileName: TFileName): AnsiString;

但我会建议您使用 TFile.ReadAllText 函数在一行代码中读取文件的内容,同时还处理文件的编码。

you code does not work because you are reading the content of the file using a unicode string as buffer, so you are just moving bytes from the internal buffer of the TFileStream to the unicode string ignoring the encoding.

you can fix easily your procedure , just changing the result type to AnsiString

function LoadFileToStr(const FileName: TFileName): AnsiString;

but i will recommend you which you use the TFile.ReadAllText function instead which in a single line of code read the content of a file a also handle the encoding of the file.

陌路黄昏 2024-11-16 14:28:14

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

Uses IOUtils;

TFile.ReadAllText(FileName);

或者

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

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

You can achieve this with one line of code using ReadAllText function. Like this:

Uses IOUtils;

TFile.ReadAllText(FileName);

or

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

It will correctly detect ANSI, Unicode and binary files.

七七 2024-11-16 14:28:14

您应该考虑编码,例如:

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;

You should take encoding into account, for example:

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;
葬﹪忆之殇 2024-11-16 14:28:14

我建议使用 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。

I recommend using a TStringList to load the content of the file and then set the result to variable.Text, for example:

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;

In this way you don't have to worry about anything, it will be backwards and future compatible IMHO.

EDIT: If you need to load from a TStream descendant, then replace LoadFromFile with LoadFromStream.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文