Как читать содержимое файла в строку в 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;


Но при выполнении этого кода в 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?

985   4  

4 ответов:

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

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

function LoadFileToStr(const FileName: TFileName): AnsiString;

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

Вы должны учитывать кодировку, например:

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;

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

Uses IOUtils;

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

Он будет правильно обнаруживать ANSI, Unicode и двоичные файлы. (Теперь я вижу, что РУз уже рекомендовал то же самое).

Я рекомендую использовать 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;

Таким образом, вам не нужно ни о чем беспокоиться, это будет обратно и будущее совместимое IMHO.

EDIT: Если вам нужно загрузить из потомка TStream, то замените LoadFromFile на LoadFromStream.

Comments

    Ничего не найдено.