2010-08-15 23 views
5

Mientras transportaba un código de Delphi 7 a Delphi 2010, estaba reescribiendo mi función LoadTextFromFile().¿Tiene Delphi 2010 una función LoadTextFromFile?

function LoadTextFromFile(const aFullFileName: string): string; 
var 
    lBuffer:  TBytes; 
    lEncoding: TEncoding; 
    lFileStream: TFileStream; 
    lSize:  Integer; 

begin 

    if not FileExists(aFullFileName) then 
    begin 
    raise Exception.Create('File "' + aFullFileName + '" not found.'); 
    end; 

    lFileStream := TFileStream.Create(aFullFileName, fmOpenRead + fmShareDenyNone); 
    try 

    if lFileStream.Size <= 0 then 
    begin 
     Result := ''; 
    end 
    else 
    begin 

     lSize := lFileStream.Size - lFileStream.Position; 

     SetLength(lBuffer, lSize); 

     // Read file into TBytes buffer 
     lFileStream.Read(lBuffer[0], lSize); 

     // Read encoding from buffer 
     TEncoding.GetBufferEncoding(lBuffer, lEncoding); 

     // Get string from buffer 
     Result := lEncoding.GetString(lBuffer); 

    end; 

    finally 
    lFileStream.Free; 
    end; 

end; 

Cuando un pensamiento me estaba golpeando en la cabeza: debe haber algo como esto en la biblioteca estándar. Muchos usuarios quieren leer un archivo de texto en una cadena, pero no pude encontrar esa función estándar. Lo más cerca que vine fue usando TStringlist para cargar texto. Pero A) crear una TStringlist parece innecesario y B) No quiero sufrir la sobrecarga de TStringlist.

Pregunta: ¿hay una función LoadTextFromFile estándar en Delphi 2010?

+0

Incluso en Delphi 7, que no tenía que hacer todo eso. Use un 'TStringStream' en lugar de un' TFileStream', y use la respuesta de Marco. Además, tengo curiosidad: ¿en qué circunstancias has encontrado que la propiedad 'Posición 'no era cero inmediatamente después de crear una secuencia, por lo que necesitarías restarla de' Tamaño' para calcular 'lSize'? –

+0

Hola Rob, en Delphi 7 Tuve que cargar/guardar en archivos UTF8. Y más importante aún, no sabía sobre TStringStream. La posición no necesita estar allí. Está ahí porque copié un código del método TStrings.Loadfromstream que tiene la posición en él. También hay otro error en mi código, ya que no maneja los archivos con BOM. Entonces, cualquiera que esté pensando en usar mi ejemplo: no lo haga. Use TFile.ReadAllText en su lugar. –

Respuesta

14

Sí existe una función como esa en Delphi 2010, se llama ReadAllText y es parte del registro TFile declarado en la unidad IOUtils.

Comprobar esta declaración

class function ReadAllText(const Path: string): string; overload; inline; static; 
class function ReadAllText(const Path: string; const Encoding: TEncoding): string; overload; inline; static; 

ver esta muestra

program Project80; 

{$APPTYPE CONSOLE} 

uses 
    IOUtils, 
    SysUtils; 
Var 
Content : string; 
begin 
    try 
    Content:=TFile.ReadAllText('C:\Downloads\test.css'); //load the text of the file in a single line of code 
    //Content:=TFile.ReadAllText('C:\Downloads\test.css',TEncoding.UTF8); //you can an encoding too. 
    Writeln(Content); 
    Readln; 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
end. 
+0

Gracias, justo lo que estaba buscando. Por curiosidad: ¿cuándo agregaron IOUtils y TFile a Delphi? –

+1

@Jan Derk: Delphi 2010. –

+2

Me di cuenta de que TFile.ReadAllText pone un bloqueo exclusivo en el archivo cuando lo lee. Hubiera preferido un bloqueo fmShareDenyWrite. –

4

TStringStream.LoadFromStream/archivo? De todos modos, las cadenas muy grandes son siempre un poco inútiles. Tienes que tener mucho cuidado para no copiarlo accidentalmente.

1

Una forma rápida es TStringList.LoadFromFile(). Luego use TStringlist.Text para acceder a los datos como una gran cadena. No te olvides de crear/libre, idealmente usando un bloque try..finally.

+2

Este método requiere muchas veces el tamaño del archivo, y no lo recomendaría para archivos grandes. –

2

Intenté la misma solución, pero hice lEncoding una variable de clase para hacerlo persistente, así que guardaría mi archivo con la misma codificación que la leí. Sin embargo, la llamada a GetBufferEncoding no hace nada si lEncoding ya está configurado en algo (como lo sería si se leyera un archivo anterior). Entonces, primero intenté liberarlo y eso causó violaciones de acceso en todo el lugar. Ahora lo configuré en cero antes de hacer la segunda llamada y parece funcionar.

Algo como esto:

if Assigned(lEncoding) then begin 
    lEncoding := nil; 
end; 
GetBufferedEncoding(buffer, lEncoding); 
Cuestiones relacionadas