30. maj 2004 - 14:35Der er
10 kommentarer og 1 løsning
delphi tutorials ?
hej.
jeg leder efter nogle gode delphi tutorial som skal lære mig at skrive til en txt fil og læse fra en + at skrive til fileofrecord og læse fra sådan. jeg har fundet en masse tutorials på netet men ikke nogen der kun handlede om disse.
hvis du kender nogle må du meget gerne smide en link op
procedure TForm1.Button1Click(Sender: TObject); const FileName = 'test0.txt'; var fp : textfile; st : string; begin assignfile(fp,FileName); if FileExists(FileName) then reset(fp) // Åbn eksisterende else rewrite(fp); // Opret ny
try st := 'Gurli Margrethe'; writeln(fp,st); finally closefile(fp); end; end;
Ved at bruge try-finally er jeg 100% sikker på at filen lukkes igen.
Når der ikke står så meget om FileOfRecord er det nok fordi at man mere bruger streams, thi de er noget mere bekvemme. Problemet med fileOfRecord er at det ikke er objektorienteret. Det er streams og det er fusdstændig ligemeget om du streamer til en socket eller en fil (der findes jo TMemoryStream, TFileStream og TSocketScream som alle nedarver fra TStream)
Først kommer lige et eksempel med FileRecords:
type TMyRecord = packed record Name : string[30]; Address : string[30]; Zip : string[10]; end;
procedure TForm1.Button2Click(Sender: TObject); const FileName = 'test1.dat'; var fp : file of TMyRecord; Person : TMyRecord; begin assignfile(fp,FileName); if FileExists(FileName) then reset(fp) // Åbn eksisterende else rewrite(fp); // Opret ny
En normal tilgang til streaming er at man pakker data efter hinanden som nul-terminerede strenge. I TMyRecord fylder data altid 73 bytes uanset om personen hedder "Ib" eller "Karl Johan Svampesen". Det eneste der er nødvendigt er at man har parret læse- og skrive-rutinerne så de ved hvordan data er lagt ud. Desuden skal man angive hvor mange data der kommer efterfølgende i "strømmen".
Det er noget med:
const FileName = 'test3.dat'
procedure TForm1.WritePerson; var fs : TFileStream; Person : TMyRecord; // Kun eksempel - smartere at lave klasse i stedet for record DataSize : integer; begin fs := TFileStream.Create(FileName,fmCreate); try Person.Name := 'Gurli Margrethe'; Person.Address := 'Kvæsthusgade 1'; Person.Zip := '1250';
// Beregn data størrelse with Person do // Lægger 1 byte til hvert element for nul-terminatoren DataSize := length(Name) + 1 + length(Address) + 1 + length(Zip) + 1;
// Skriv den til filen fs.Write(DataSize,sizeof(integer));
fs.WriteBuffer(pchar(Person.Name)^,length(Person.Name) + 1); fs.WriteBuffer(pchar(Person.Address)^,length(Person.Address) + 1); fs.WriteBuffer(pchar(Person.Zip)^,length(Person.Zip) + 1); finally fs.Free; // Nu har vi læst data ind i buffer - luk stream end; end;
procedure TForm1.ReadPerson; var fs : TFileStream; Person : TMyRecord; // Kun eksempel - smartere at lave klasse i stedet for record DataSize : integer; Buffer, p : pchar; // Buffer som data hentes ind i begin fs := TFileStream.Create(FileName,fmOpenRead); try fs.Read(DataSize,sizeof(integer)); // Læs de antallet af efterfølgende bytes GetMem(buffer,DataSize); p := buffer; // Sæt pegeinden til start af buffer try fs.ReadBuffer(Buffer^,DataSize); finally fs.Free; // Nu har vi læst data ind i buffer - luk stream end;
// En pchar er nul-termineret, men der er data bagefter den - derfor flytter // vi med p, mens Buffer-variablen skal bruges til at frigive den allokerede // hukommelse med.
Person.Name := string(p); // Læs første streng p := StrEnd(p) + 1; // Flyt pegepinden forbi første streng
Person.Adress := string(p); p := StrEnd(p) + 1; // Flyt pegepinden forbi anden streng
Tidligere var BlockWrite og BlockRead begrænset til data-klumper af maksimalt 32kb - Det ser ud til at være ændret nu, til en størrelse begrænset af 32-bit, dvs: 2Gb (da variablen er en signed integer)
Glemte i øvrigt at sige, at sidstnævnte eksempel kun er egnet til sekventiel gennemlæsning af data. Med blockread/write og streamede records kan man flytte frem og tilbage med hhv. seek() og fs.Position := x. Det kan man ikke i det sidste eksempel da recordstørrelsen er variabel; man er nødt til at gennemløbe listen fra ende til anden for at finde en given record.
type // Strengstørrelser skal angives da "string" uden angivelse er variabel - for // at recordstørrelsen skal være ens, må datatyperne være faste. TDataRec = packed record Data : String[20]; end;
procedure TForm1.ConvertData; var TxtFile : TTextFile; RecFile : file of TDataRec; st : string; Rec : TDataRec; begin assignfile(TxtFile,'data.txt'); assignfile(RecFile,'data.dat');
reset(TxtFile); rewrite(RecFile);
try while not TxtFile.Eof do begin readln(TxtFile,st); Rec.Data := st; // Bemærk, hvis length(st) > 20 så trunkeres data blockwrite(Rec,sizeof(TDataRec)); end; finally closefile(RecFile); closefile(TxtFile); end; end;
procedure TForm1.ConvertDataTheOtherWay; var TxtFile : TTextFile; RecFile : file of TDataRec; st : string; Rec : TDataRec; begin assignfile(TxtFile,'data.txt'); assignfile(RecFile,'data.dat');
rewrite(TxtFile); reset(RecFile);
try while not RecFile.Eof do begin blockread(RecFile,Rec,sizeof(TDataRec)); st := Rec.Data; writeln(TxtFile,st); end; finally closefile(RecFile); closefile(TxtFile); end; end;
Synes godt om
Ny brugerNybegynder
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.