Как читать содержимое файла в строку в 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?
4 ответов:
Ваш код не работает, потому что Вы читаете содержимое файла, используя строку юникода в качестве буфера, поэтому вы просто перемещаете байты из внутреннего буфера TFileStream в строку Юникода, игнорируя кодировку.
Вы можете легко исправить свою процедуру, просто изменив тип результата на
AnsiStringfunction 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