01. december 1999 - 00:58Der er
21 kommentarer og 1 løsning
læsning og skrivning til tekstfiler
Hej allesammen
Hvad dælen er der galt med dette kode jeg får en i/o 103 fejl når jeg vil gemme dataen til en fil der eksistere i forvejen.
procedure TForm1.Button40Click(Sender: TObject); Var s,s2:string; f: textfile; i,j:integer; begin
if not(fileexists('destdata.txt')) then begin Assignfile(f,'destdata.txt'); Rewrite(F); end else begin Assignfile(f,'c:\borland\pictureplacer\destdata.txt'); Reset(f); end;
for i:=1 to 18 do begin s:=form1.edit3.text+'ses'; // seek(f,0); writeln(f,s); end; closefile(f);
Når du bruger Reset åbner du kun filen til læsning...... Jeg ved ikke helt hvad det helt præcis er du vil, men slå op i hjælpen under reset eller rewrite, og se så hvad det er for en procedure du skal bruge (Kunne forestile mig append eller rewrite)
Hvad med at læse hele text filen ind i en TStringList. Lave de ændringer der skal til og så skrive den ud igen?
Hvis filen har en overkommelig størrelse, dvs. under nogle tusinde linier, og maskinen er bare lidt nyere end en IBM-XT, så burde dette ikke tage nævneværdig lang tid.
Som I kan se af mit svar/kommentar er det ikke kun under skrivning af filer der opstår fejl.
Stavefejl opstår af en eller anden årsag fra det øjeblik man sender sit indlæg til det når frem. Jeg tror sgu' der må være noget galt med eksperten :-)
Sjensen> Dit forslag er se'følig det oplagte, hvis man ønsker at tilføje linier til en text fil. Men af en eller anden grund, sidder jeg med den opfattelse, at Gartneren egentligt ønsker at enten overskrive de første linier i filen eller at tilføje i starten af filen (bl.a. pga. hans Seek(f,0) - iøvrigt endnu en kommando der heller ikke kan benyttes på text files. I såfald er Append ikke den rigtige løsning.
Delphi> Helt korrekt. Hvis det er tilfældet, og det kan man som du ganske rigtigt påpeger formode ud fra seek(f,0), så er en mulig løsning en listboks med loadfromfile, tilføjelse af linier med insert og så savetofile igen, som du foreslår.
Hvis det er NT så betyder de ikke noget at filen er noget større. Jeg læser ofte filer med 10-15.000 recs eller mere ind på den måde og det går rimeligt hurtigt. For rigtigt store filer skal man bare huske at sætte timeglasset så man kan se at der sker noget for det vil tage lidt tid, men til gengæld er begrænsningen jo "kun" 2,147mia tegn så...
Selvfølgelig er der muligheden for at åbne filen med reset og en anden med rewrite, skrive de linier men vil i den nye og læse resten fra den oprindelige og skrive dem i den nye også. På denne på denne måde kan man endda indsætte dem der hvor man vil midt i det loop man laver. Efterfølgende skal man så lukke filerne igen og endeligt slette den oprindelige og rename den nye til det gamle navn. Men.. Det er jo lige netop det loadfrom og saveto gør. Og det vi gjorde i gamle dage under DOS. Med Delphi er man endeligt sluppet for det så jeg siger bare "Hurra for Delphi's Listbox".
Hvorfor bruger du en listbox? Det giver kun extra overhead - rent bortset fra at du skal ha' oprettet en listbox på en form osv. Gør som Listbox'en selv og bennyt en Stringlist:
Var FileList : TStringList; begin FileList : TStringList.Create; Try FileList.LoadFromFile(FileName); For Index := 0 to NoStrings Do FileList.Insert(0, StringNo[Index]); FileList.SaveToFile(FileName); Finally FileList.Free; End; end;
Selvfølgelig, det gør jeg normalt også hvis jeg ikke samtidig vi se hvad det er jeg læser ind og behandler. Men det meste af tiden er det records der skal behandles, omstruktureres, koder der skal erstattes med tekst, sorteres o.s.v. og for det meste viser jeg denne behandling for brugeren så de kan se hvad der sker. Det er altid en god ide at lade brugeren se hvad der foregår, specielt hvis det er noget der tager langt tid.
I mindre funktioner, og hvor jeg ellers har brug for at flytte data fra filer til program og vise versa, eller mellem funktioner, bruger jeg selvfølgelig TStringlist.
F.eks. når jeg arbejder med kommasep. filer er Listbox's og Stringlist CommaText property bare genial, selvom den ikke er helt korrekt. Men de få skavanker den har har jeg lært at leve med og håndterer dem selv.
Hvis du skal skrive en ny fil lige meget hvad, slet filen hvis den eksisterer:
if fileexists ('c:\borland\pictureplacer\destdata.txt') then DeleteFile ('c:\borland\pictureplacer\destdata.txt') Assignfile(f,'destdata.txt'); Rewrite(F);
for i:=1 to 18 do begin s:=form1.edit3.text+'ses'; writeln(f,s); end; closefile(f);
Delphi> Overskrive eksisterende ? Næh.. ikke lige på den måde Stoons foreslår det på, med mindre current dir og drev tilfældigvis er "C:\borland\pictureplacer" !!
Stoons> Som delphi siger overskriver ReWrite ganske rigtigt den fil der tilfældigvis er der hvor ReWrite skriver, men i dit eks. kan han rent faktisk komme til at slette en fil i C:\borland\pictureplacer der tilfældigvis hedder "destdata.txt", men linien AssignFile('Destdata.txt'); betyder ikke automatisk at den nye fil oprettes i samme dir. Den bliver oprettet på currentdir på current disk, hvilket jo udmærket kan være noget andet. Så.. jeg håber da ikke at det er sådan du selv laver programmer, får så vil jeg kunne forstå hvis du ind imellem havde problemer med forsvundne og underligt placerede filer :-)
Linien skulle naturligvis have været Assignfile('C:\Borland\PicturePlace\Destdata.txt'); men det var selvfølgeligt også det du mente, ikke også ? ;-)
>det var selvfølgeligt også det du mente, ikke også
Det var ihvertfald det jeg gik stærkt ud fra. Er denne tråd iøvrigt ikke temmelig død efterhånden - Svarene der er giver er go'e og resten er løbet op i petitesser....
Jeg havde et problem for nylig, hvor jeg brugte en memobox's loadfromfile som også virkede OK.
Men nogle gange når jeg prøvede at tildele er streng til f.eks. Memo1.Lines[0] blev resultatet det som jeg tildelte men med en masse tilfældige tegn efter og som blev gemt når jeg brugte SaveToFile.
Jeg gik derfor over til at bruge et dynamisk array hvorefter jeg ikke havde flere problemr med mystiske ekstra tegn.
Måske skulle jeg have brugt en TStringList men det er jo det samme som Memobox'en gør.
Hvorfor Memobox komponenten opførte sig mærkelig har jeg stadig ikke fundet ud af.
hlj> når man sætter en streng ind i en memo som du gør i eksemplet bliver strengen automatisk tilført CR og LF (hex. 0D og 0A, dec. #13 og #10)
Disse vil du kunne se afhængigt af hvilket program du bruger. Hvis du f.eks. viser en meno i en Tedit.text vil du typisk se 2 underlige tegn midt i teksten, men hvis du kigger efter er det der hvor du i memoen skifter linie. Disse tegn kommer ikke hvis du bare indtaster data i en memo UDEN at trykke på ENTER/RETURN for at få en ny linie, men lader memoen "Wrappe" teksten automatisk.
Der er formentligt det der sker.
Noget andet er at du burde oprette dit spørgsmål som et separat spm og så tildele point for svaret.
sjensen> Jeg godt klar over at der kan blive indsat et CR + LF i en streng, men hvis jeg skrev Memo1.Lines[0] := 'Hej med dig'; resulterede det i at når jeg så linien visuelt i Memobox'en, kunne der f.eks. stå : Hej med digwqq6743q eller lignede.
Hvorfor den gjorde det har jeg ingen anelse om.
Jeg har iøvrigt lige før tildelingen udført følgende kommandoer:
Tak til jer alle der er kommet med disse indlæg. Jeg har fået løst problemet med filen ved simpelthen at slette den og lave den igen på ny. det er dog ikke den optimale løsning, men den virker.
>>Delphi du havde ret det der med at slette noget inde i filen og så skrive den igen. Godt set !
/Hilsen Gartner76
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.