Uso de corrientes (streams) para leer un archivo en una cadena (string) y para grabar el contenido de una cadena en un archivo

Leyendo y grabando un archivo en y desde una cadena

Copyright © 2000 Ernesto De Spirito

KnowledgeBase Vortex 2.9

Leyendo un archivo en una cadena

Tal vez la forma más fácil de leer un archivo en una cadena sea usando el método LoadFromFile de un objeto TStringList y luego accediendo a su propiedad Text:

uses SysUtils, Classes;

function LoadFile(const FileName: TFileName): string;
begin
  with TStringList.Create do
    try
      LoadFromFile(FileName);
      Result := Text;
    finally
      Free;
    end;
end;

Sin embargo, esta forma de hacer las cosas es ineficiente dado que LoadFromFile carga el fichero y separa las líneas, y luego cuando usamos la propiedad Text, se llama internamente a un método que produce una cadena juntando las líneas, así que este doble trabajo es realizado para nada, además que se termina usando más del doble de memoria que realmente se necesita (hasta que se libera el objeto TStringList).

Una forma mejor

Un enfoque mejor sería usar un objeto TFileStream (o los viejos procedimientos Assign, Reset, Read y Close) para leer directamente el contenido de un archivo en una cadena. Aquí usamos TFileStream para implementar la misma función de arriba que devuelve el contenido de un archivo cuyo nombre se pasa como parámetro:

uses SysUtils, Classes;

function LoadFile(const FileName: TFileName): string;
begin
  with TFileStream.Create(FileName,
      fmOpenRead or fmShareDenyWrite) do begin
    try
      SetLength(Result, Size);
      Read(Pointer(Result)^, Size);
    except
      Result := '';  // Deallocates memory
      Free;
      raise;
    end;
    Free;
  end;
end;

Grabando un archivo desde una cadena

Si necesitáramos guardar los contenidos de una cadena en un archivo, podemos usar el siguiente procedimiento:

uses SysUtils, Classes;

procedure SaveFile(const FileName: TFileName;
                   const content: string);
begin
  with TFileStream.Create(FileName, fmCreate) do
    try
      Write(Pointer(content)^, Length(content));
    finally
      Free;
    end;
end;
JfControls Library - para Delphi y C++ Builder