Как прочитать содержимое файла в строку в Delphi XE - PullRequest
10 голосов
/ 24 мая 2011

Я переношу свое приложение из 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, но результат будет таким же.

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

Ответы [ 4 ]

26 голосов
/ 24 мая 2011

ваш код не работает, потому что вы читаете содержимое файла, используя в качестве буфера строку Unicode, поэтому вы просто перемещаете байты из внутреннего буфера TFileStream в строку Unicode, игнорируя кодировку.

Вы можете легко исправить вашу процедуру, просто изменив тип результата на AnsiString

function LoadFileToStr(const FileName: TFileName): AnsiString;

, но я порекомендую вам использовать функцию TFile.ReadAllText вместо одной в однойстрока кода читает содержимое файла, а также обрабатывает кодировку файла.

13 голосов
/ 27 февраля 2014

Вы можете достичь этого с помощью одной строки кода, используя функцию ReadAllText.Например:

Uses IOUtils;

TFile.ReadAllText(FileName);
TFile.ReadAllText(FileName, s, TEncoding.ASCII) // force encoding 

Он будет правильно определять ANSI, Unicode и двоичные файлы.

9 голосов
/ 24 мая 2011

Необходимо учитывать кодировку, например:

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 голосов
/ 24 мая 2011

Я рекомендую использовать TStringList для загрузки содержимого файла, а затем установить результат в переменную. Текст, например:

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.

...