web-dev-qa-db-ja.com

デルファイXEでファイルの内容を文字列に読み取る方法

アプリケーションを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?

10
DelphiNewbie

バッファとしてUnicode文字列を使用してファイルのコンテンツを読み取っているため、コードは機能しません。したがって、エンコーディングを無視して、TFileStreamの内部バッファからUnicode文字列にバイトを移動しているだけです。

結果タイプをAnsiStringに変更するだけで、プロシージャを簡単に修正できます。

function LoadFileToStr(const FileName: TFileName): AnsiString;

しかし、私はあなたが使用することをお勧めします TFile.ReadAllText 代わりに、1行のコードでファイルのコンテンツを読み取り、ファイルのエンコードも処理する関数。

26
RRUZ

これは、ReadAllText関数を使用して1行のコードで実現できます。このような:

Uses IOUtils;

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

ANSI、Unicode、およびバイナリファイルを正しく検出します。

13
WeGoToMars

次に、エンコーディングを考慮する必要があります。

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;
9
kludg

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に置き換えます。

6
ComputerSaysNo