Trabalhar com arquivos textos no Lazarus é bem fácil. Há várias maneiras de se tratar arquivos textos, desde o velho modo do Pascal (AssignFile/Reset/Rewrite/Append/CloseFile) aos métodos (LoadFromFile/SaveToFile) dos descendentes de TStrings. Mas para trabalhar com arquivos grandes é mais eficiente usar TFileStream.
Para demonstrar o uso do TFileStream montei um pequeno exemplo no Lazarus, como mostra a imagem abaixo.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
unit Unit1; | |
{$mode objfpc}{$H+} | |
interface | |
uses | |
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls; | |
type | |
{ TForm1 } | |
TForm1 = class(TForm) | |
Memo1: TMemo; | |
ButtonAbrir: TButton; | |
ButtonSalvar: TButton; | |
OpenDialog1: TOpenDialog; | |
SaveDialog1: TSaveDialog; | |
procedure ButtonAbrirClick(Sender: TObject); | |
procedure ButtonSalvarClick(Sender: TObject); | |
private | |
{ private declarations } | |
public | |
{ public declarations } | |
end; | |
var | |
Form1: TForm1; | |
implementation | |
{$R *.lfm} | |
{ TForm1 } | |
procedure TForm1.ButtonAbrirClick(Sender: TObject); | |
var | |
Buf: Byte; | |
Linha: String; | |
FileStreamTxt: TFileStream; | |
begin | |
if OpenDialog1.Execute then | |
try | |
FileStreamTxt := TFileStream.Create(OpenDialog1.FileName, fmOpenRead or fmShareDenyNone); | |
Linha := ''; | |
Memo1.Clear; | |
while (FileStreamTxt.Position <= FileStreamTxt.Size - 1) do begin | |
FileStreamTxt.Read(Buf, 1); | |
Linha := Linha + Chr(Buf); | |
if (Pos(LineEnding, Linha) > 0) or (FileStreamTxt.Position = FileStreamTxt.Size) then begin | |
Memo1.Lines.Add(StringReplace(Linha, LineEnding, '', [rfReplaceAll, rfIgnoreCase])); | |
Linha := ''; | |
end; | |
end; | |
finally | |
FreeAndNil(FileStreamTxt); | |
end; | |
end; | |
procedure TForm1.ButtonSalvarClick(Sender: TObject); | |
var | |
Linha: String; | |
Indice: Integer; | |
FileStreamTxt: TFileStream; | |
begin | |
if Memo1.Lines.Count > 0 then | |
if SaveDialog1.Execute then | |
try | |
FileStreamTxt := TFileStream.Create(SaveDialog1.FileName, fmCreate or fmShareDenyWrite); | |
for Indice := 0 to Memo1.Lines.Count - 1 do begin | |
Linha := Memo1.Lines.Strings[Indice] + LineEnding; | |
FileStreamTxt.WriteBuffer(Linha[1], Length(Linha)); | |
end; | |
finally | |
FreeAndNil(FileStreamTxt); | |
end; | |
end; | |
end. |
Bem, o projeto acima pode não demonstrar a eficiência do TFileStream, mas mostra a simplicidade de usá-lo. Basicamente a única coisa que precisamos nos preocupar é com o LineEnding que marca o fim de cada linha de um arquivo texto. Talvez um bom exemplo seja a gravação de dados em um arquivo de log de grande tamanho. Neste caso, o código para salvar as linhas ficaria bem parecido com o método ButtonSalvarClick, do exemplo acima. A única coisa que mudaria seria a linha abaixo:
FileStreamTxt := TFileStream.Create(SaveDialog1.FileName, fmCreate or fmShareDenyWrite);
A qual seria melhor substituída pelo seguinte trecho:
if FileExistsUTF8(SaveDialog1.FileName) then begin
FileStreamTxt := TFileStream.Create(SaveDialog1.FileName, fmOpenWrite or fmShareDenyWrite);
FileStreamTxt.Position := FileStreamTxt.Size;
end else begin
FileStreamTxt := TFileStream.Create(SaveDialog1.FileName, fmCreate or fmShareDenyWrite);
end;
Outra ressalva a fazer, no método ButtonAbrirClick, é que o comando TMemo.Lines.Add adiciona automaticamente o LineEnding, sendo necessário, neste caso, remover este da linha a ser inserida, usando o comando StringReplace. Se for tratar o arquivo diretamente no TFileStream talvez não seja necessário usar este recurso.
Esta dica deve funcionar no Windows, Linux e Mac. Mais informações em: http://wiki.freepascal.org/File_Handling_In_Pascal
[]'s,
Ericson Benjamim.
Nenhum comentário:
Postar um comentário