Avatar billede phi-del Nybegynder
30. maj 2004 - 14:35 Der 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
Avatar billede stone Forsker
30. maj 2004 - 16:12 #1
skriv til memo....tekst skrives

memo1.lines.savetofiles('test.txt');


hente fil...

memo1.lines.loadfromfiles('test.txt');//filen bliver placeret i samme bib som exe´fil

det er essensen i at write/read txt file
Avatar billede stone Forsker
30. maj 2004 - 16:14 #2
skal filen placeres anden lokalitet

('c:\temp\test.txt');
Avatar billede phi-del Nybegynder
30. maj 2004 - 17:03 #3
procedure TForm1.Button1Click(Sender: TObject);
var f:textfile;
a:string;

begin

a:=edit1.Text;
writeln(f,a);
closefile(f);


jamen er der nogen der kan se hvorfor denne ikke virker ?
Avatar billede hrc Mester
30. maj 2004 - 17:55 #4
Du har glemt et par ting i ovenstående:

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

  try
    Person.Name := 'Gurli Margrethe';
    Person.Address := 'Kvæsthusgade 1';
    Person.Zip := '1250';

    BlockWrite(fp,Person,1); // Skriv een record
  finally
    closefile(fp);
  end;
end;

Skulle det have været streamet så var det blevet sådan her:

procedure TForm1.Button3Click(Sender: TObject);
const
  FileName = 'test2.dat';
var
  fs : TFileStream;
  Person : TMyRecord;
begin
  if FileExists(FileName) then
    fs := TFileStream.Create(FileName, fmOpenWrite)
  else
    fs := TFileStream.Create(FileName, fmCreate);

  try
    Person.Name := 'Gurli Margrethe';
    Person.Address := 'Kvæsthusgade 1';
    Person.Zip := '1250';

    fs.WriteBuffer(Person,sizeof(TMyRecord));
  finally
    fs.Free;
  end;
end;
Avatar billede hrc Mester
30. maj 2004 - 18:12 #5
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

    Person.Zip := string(p);
  finally
    FreeMem(Buffer);
  end;
end;
Avatar billede hrc Mester
30. maj 2004 - 18:56 #6
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)

Håber at det besvarer dit spørgsmål.
Avatar billede hrc Mester
31. maj 2004 - 11:24 #7
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.
Avatar billede phi-del Nybegynder
03. juni 2004 - 00:14 #8
hvad nu hvis jeg skal , først læse fra en tekst fil og senere skal lave den om til en fileofreccord. hvordan ser denne kode ud ?

læs fra fileofrecord og smide dem i en textfil  (hvordan vil den se ud ?
Avatar billede hrc Mester
03. juni 2004 - 10:07 #9
Det må være noget i retning af dette

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;
Avatar billede hrc Mester
03. juni 2004 - 10:08 #10
Rettelse: blockwrite(RecFile,Rec,sizeof(TDataRec));
Avatar billede hrc Mester
03. juni 2004 - 10:10 #11
Den anden vej kan se sådan her ud:

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;
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