2011-05-23 25 views
8

Estoy migrando mi aplicación de delphi 2007 a delphi xe, pero tengo problemas con un procedimiento que lee un archivo (ascii) y almacena el contenido en una cadenaCómo leer el contenido del archivo en una cadena en delphi XE

este es el código que funcionan bien en 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; 

pero cuando ejecuta este código en Delphi XE el resultado son sólo símbolos como '????????', sé lo que Delphi XE es unicode entonces cambio estas líneas

 SetLength(Result, FileStream.Size); 
     FileStream.Read(Pointer(Result)^, FileStream.Size); 

a

 SetLength(Result, FileStream.Size*2); 
     FileStream.Read(Pointer(Result)^, FileStream.Size); 

para almacenar el contenido del archivo en la cadena Unicode pero el resultado es el mismo.

how i can fix this procedure to read the content of this file?

+2

Tenga cuidado con TStringList, porque si el archivo 'texto' de alguna manera contiene caracteres ASCII NUL (0x00), el analizador se detiene y termina con menos líneas que en realidad en el archivo. –

Respuesta

24

que el código no funciona debido a que está leyendo el contenido del archivo usando una cadena Unicode como tampón, por lo que se desplaza únicamente bytes desde el buffer interno de la TFileStream a la cadena Unicode haciendo caso omiso de la codificación .

usted puede fijar fácilmente su procedimiento, simplemente cambiando el tipo de resultado a AnsiString

function LoadFileToStr(const FileName: TFileName): AnsiString; 

pero voy a recomendar que se utiliza la función TFile.ReadAllText vez que a una sola línea de código de leer el contenido de un archivo a también maneja la codificación del archivo.

8

Usted debe tomar en cuenta la codificación, por ejemplo:

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

recomiendo el uso de un TStringList para cargar el contenido del archivo y luego ajustar el resultado a variable.Text, por ejemplo:

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; 

De esta manera, no tiene que preocuparse por nada, será al revés y en el futuro compatible con mi humilde opinión.

EDITAR: Si necesita cargar desde un descendiente TStream, entonces reemplace LoadFromFile con LoadFromStream.

8

Puede lograr esto con una línea de código utilizando la función ReadAllText. De esta manera:

Uses IOUtils; 

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

Se detectará correctamente ANSI, Unicode y archivos binarios. (Ahora veo que RRuz ya me recomendó lo mismo).

Cuestiones relacionadas