2011-05-23 77 views
8

我正在將我的應用程序從delphi 2007遷移到delphi xe,但我有一個讀取文件(ascii)並將內容存儲在字符串如何讀取文件的內容到一個字符串在德爾福XE

這是一個好的工作在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; 

但是當德爾福XE執行此代碼的結果就像是「????????」符號,我知道德爾福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?

+2

小心TStringList,因爲如果'文本'文件以某種方式包含ASCII NUL(0x00)字符,分析器將停止並且最終的文件行數少於實際文件。 – 2012-11-23 16:15:41

回答

24

,因爲你正在閱讀使用Unicode字符串作爲緩衝區的文件的內容,您的代碼不工作,所以你只是從TFileStream的對Unicode字符串的內部緩衝區移動字節忽略編碼。

,你可以很容易地解決您的程序,只是改變了結果類型AnsiString

function LoadFileToStr(const FileName: TFileName): AnsiString; 

,但我會建議你,你使用TFile.ReadAllText功能,而不是它在一個單一的代碼行讀取文件的內容一個也處理文件的編碼。

8

你應該採取的編碼進去,例如:

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

我建議使用的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後裔加載,然後用LoadFromStream替換LoadFromFile。

8

您可以通過使用ReadAllText函數的一行代碼來實現此目的。像這樣:

Uses IOUtils; 

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

它會正確檢測ANSI,Unicode和二進制文件。 (現在我看到RRuz已經推薦相同)。