アプリケーションをdelphi2007からdelphixeに移行していますが、ファイル(ascii)を読み取ってコンテンツを文字列に格納する手順に問題があります。
これはdelphi2007で問題なく動作するコードです
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がユニコードであるかがわかっているので、これらの行を変更します。
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?
バッファとしてUnicode文字列を使用してファイルのコンテンツを読み取っているため、コードは機能しません。したがって、エンコーディングを無視して、TFileStreamの内部バッファからUnicode文字列にバイトを移動しているだけです。
結果タイプをAnsiString
に変更するだけで、プロシージャを簡単に修正できます。
function LoadFileToStr(const FileName: TFileName): AnsiString;
しかし、私はあなたが使用することをお勧めします TFile.ReadAllText
代わりに、1行のコードでファイルのコンテンツを読み取り、ファイルのエンコードも処理する関数。
これは、ReadAllText関数を使用して1行のコードで実現できます。このような:
Uses IOUtils;
TFile.ReadAllText(FileName);
TFile.ReadAllText(FileName, s, TEncoding.ASCII) // force encoding
ANSI、Unicode、およびバイナリファイルを正しく検出します。
次に、エンコーディングを考慮する必要があります。
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;
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に置き換えます。