Avatar billede futterama Nybegynder
18. oktober 2004 - 11:52 Der er 14 kommentarer og
1 løsning

Append tekst til tekstfil med SaveToFile

Hej,

Som borrisholt altid siger: Man bruger Streams og SaveToFile, men hvordan gemmer man noget til en eksisterende fil uden at overskrive indholdet?

MVH
Futterama
Avatar billede borrisholt Novice
18. oktober 2004 - 11:55 #1
Fbuffer er en privat TStringList hvori du har in text
procedure SaveToFile(const Filename : String);
begin
  if FileExists(FileName) then
    Fbuffer.LoadFromFile(fileName)
  Fbuffer.Add(TextToAppend);
  FBuffer.SaveTofile(Filename)

end;
Avatar billede futterama Nybegynder
18. oktober 2004 - 12:02 #2
Som jeg har læst lidt om her på siden, så indlæser man indholdet af filen for at tilføje noget... men når man som i mit tilfælde er ved at lave et program der genererer store filer (flere GB) så er det meget uhensigtmæssigt at indlæse det hele hver gang...

Men måske jeg også griber det forkert an. Programmet skal bare lave en textfil af en hvis størrelse med tilfældige (eller ens) tegn. Mit program skriver til en fil i en lykke. Den skriver i blokke af 1KB da jeg fandt ud af at det er hurtigst (i forhold til 1MB osv.).

Men er der nogle med en god ide, så spyt ud ;-)
Avatar billede doc404 Novice
18. oktober 2004 - 12:33 #3
var
  fs : TFileStream;
...
  fs := TFileStream.Create(FileName,fmOpenWrite);
  fs.Seek(0,soFromEnd);
  ...
  nu kan du tilføje til filen med fs.Write()
  ..
  FreeAndNil(fs);
Avatar billede hrc Mester
18. oktober 2004 - 13:01 #4
Eller for at demonstrere den oprindelige pascal-version idet der vist ikke er noget lettere når det drejer sig om tekstfiler:

const
  FileName = 'GiganticLogFile.log';
var
  fp : Textfile;
begin
  assignfile(fp,FileName);
  if FileExists(FileName) then
    append(fp)
  else
    rewrite(fp);
  try
    writeln(fp,'Yet another line added');
  finally
    closefile(fp);
  end;
end;
Avatar billede futterama Nybegynder
19. oktober 2004 - 10:35 #5
Argh, enten er jeg en døt til det her, eller også virker det bare ikke...
Avatar billede hrc Mester
19. oktober 2004 - 14:25 #6
Vi kan alle være døt'ter til dette her - som regel er det et manglende semikolon eller lignende.

Hvilken løsning har du prøvet at lave?
Avatar billede futterama Nybegynder
19. oktober 2004 - 14:30 #7
Jeg slettede det desværre igen i arrigskab... Men jeg prøver igen lidt senere på ugen, kan være jeg har mere held med mig dér...
Avatar billede hrc Mester
21. oktober 2004 - 16:40 #8
Se http://www.eksperten.dk/spm/552059 (nederst) for et eksempel på hvordan man bruger TReader og TWriter objekterne.
Avatar billede futterama Nybegynder
22. oktober 2004 - 07:37 #9
Hvis filen exists så får jeg en stream write error... men ellers er det et fint eksempel, nu vil jeg så lige teste hastigheden...
Avatar billede futterama Nybegynder
22. oktober 2004 - 07:47 #10
Og hvad er det lige for nogle ekstra tegn den sætter ind i starten af filen?
Min kode er som følger:

procedure TForm1.Button1Click(Sender: TObject);
var
  fs : TFileStream;
  Writer : TWriter;
  Thing: String;
  i: Integer;
begin
  for i := 1 to 1000000 do
    Thing := Thing + '1'; //Fyld variablen med 1 mio. 1-taller

  if FileExists('d:\test.tst') then
    DeleteFile('d:\test.tst'); //Hvis filen eksisterer så slet den

  fs := TFileStream.Create('d:\test.tst', fmCreate); //Opret filen
  fs.Seek(0, soFromEnd); //Er vel ikke nødvendigt når jeg kun skal oprette nye filer

  Writer := TWriter.Create(fs, 1000000);
  try
    for i := 1 to 10 do
      Writer.WriteString(Thing); //Skriv 1 mio. 1-taller til filen 10 gange
    Label1.Caption := 'Done!'; //Giv besked om at filen er færdig
  finally
    Writer.Free;
    fs.Free;
  end;
end;
Avatar billede futterama Nybegynder
22. oktober 2004 - 08:02 #11
I forhold til min "gamle" måde at skrive en stor fil, så er streams meget hurtigere. For at skrive en 10MB fil, tog det med den gamle metode 1,5sek med streams tager det kun 0,5sek så det er jo gode nyheder :-)
Avatar billede futterama Nybegynder
22. oktober 2004 - 08:04 #12
hrc, hvis du laver et svar, så vil jeg give dig pointene, for med din metode kan jeg få det til at virke og det går hurtigt :-)
Avatar billede futterama Nybegynder
04. november 2004 - 08:37 #13
Well, så lukker jeg selv af ;-)
Avatar billede hrc Mester
04. november 2004 - 08:56 #14
Damn! Den overså jeg, men godt at du har fået det til at virke. Har selv leget noget med TWriter og TReader og endte, pga. problemer med at indlæse strenge (aner stadig ikke hvor det går galt), med at bruge goe' gamle textfile.
Avatar billede futterama Nybegynder
04. november 2004 - 09:00 #15
Jeps, det virker, og kan da lige smide koden herind for god ordens skyld:

FileStream := TFileStream.Create(SaveDialog.Filename, fmCreate); //Create the file
try
  for i := 1 to StrToInt(EdFileSize.Text) * Count do
  begin
    if Cancel then
      Break;
    ProgressBar.Position := Round(i);
    Application.ProcessMessages;
    FileStream.Write(WriteThing[1], LENGTH(WriteThing)); //Write the string to the file
  end;
finally
  FileStream.Free
end;
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester