Autor Beitrag
Amiga-Fan
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 534



BeitragVerfasst: Fr 18.03.05 15:36 
wisst Ihr vielleicht wie man eine Textdatei rückwärts auslesen kann ohne die gesamten Daten im Speicher zu halten? Ich habe es versucht.... In ein Array einlesen würde zu viel Arbeitsspeicher kosten (die Textdatei ist immerhin 13 MB groß).

ich habe ein Importprogramm und das schreibt die INSERT und zugehörigen DELETE (um das ganze wieder rückgängig zu machen) - Befehle in jeweils eine separate Datei. Aber wenn ich mit dem Delete-Skript das Einfügen rückgängig machen will muß ich das natürlich rückwärts angehen.
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Fr 18.03.05 15:38 
gehe mit seek an das (eof des files) - 1, und dann immer ein char einlesen, mit seek wieder ein byte zurück usw

_________________
es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Fr 18.03.05 15:53 
Ich würde auch retnyg's Vorschlag probieren.
Was auch ginge: Du kannst dir einen Bereich im Virtual Memory Space direkt einer Datei zuordnen. Wenn du dann von diesem Memorybereich liest, wird nicht vom RAM sondern von der Festplatte gelesen. Du kannst dann im Delphi ein normales Array definieren - wenn du darauf zugreifst, wird direkt von einer Datei gelesen oder geschrieben!
Siehe memory mapped files (mmap/munmap) auf msdn oder Google. Habs aber selbst noch nie probiert.
Amiga-Fan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 534



BeitragVerfasst: Fr 18.03.05 15:59 
Danke. Hm klappt noch nicht, in der Zieldatei stehen nur Nullen oder Einsen :D

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
    
var
    QuellDatei:file of Byte;
    ZielDatei: Textfile;
    tmpChar:byte;
begin
  try
    AssignFile(QuellDatei,sFilePath+'Delete.sql');                // SQL-Statement ins Insert.sql Script schreiben
    Reset(QuellDatei);

    DeleteFile(sFilePath+'Delete2.sql');
    AssignFile(ZielDatei,sFilePath+'Delete2.sql');                // SQL-Statement ins Insert.sql Script schreiben
    Rewrite(ZielDatei);

    x:=filesize(QuellDatei)-1;
    while x>=0 do begin
      x:=filesize(QuellDatei)-1;
      seek(Quelldatei,x);
      read(QuellDatei,tmpChar);
      dec(x);
      Write(ZielDatei,tmpChar);
    end;

    CloseFile(QuellDatei);
    CloseFile(ZielDatei);

    [...]
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Fr 18.03.05 16:00 
Zitat:
ausblenden Delphi-Quelltext
1:
2:
3:
    x:=filesize(QuellDatei)-1;
    while x>=0 do begin
      x:=filesize(QuellDatei)-1;

warum 2mal die filesize lesen ?

_________________
es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
Amiga-Fan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 534



BeitragVerfasst: Fr 18.03.05 16:02 
nur um zu initialisieren, damit er in die Schleife reinspringt.

Habe gerade Textfile durch file of byte ersetzt, reicht aber nicht. Hm wenn ich das so mache wird er vermutlich auch die Befehle rückwärts schreiben, da muss ich mir noch was einfallen lassen...
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Fr 18.03.05 16:03 
Ausserdem würd ich die Datei nicht Byte-weise lesen, sondern Blockweise.
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Fr 18.03.05 16:05 
user profile iconAmiga-Fan hat folgendes geschrieben:
nur um zu initialisieren, damit er in die Schleife reinspringt.

da sich die filesize nie ändert, wird aber auch X nie NULL sein ?
ich würde das 2te da mal weg machen, und es mit einem file of char probieren.

_________________
es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
Amiga-Fan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 534



BeitragVerfasst: Fr 18.03.05 16:06 
hm seek scheint jedenfalls nur mit file of byte aber nicht mit textfile zu funktionieren...
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Fr 18.03.05 16:08 
Das Seek funktioniert mit TextFiles nicht. TextFile verwendet zum lesen/schreiben einen Buffer, deswegen kannst du nicht seeken.
(Du musst dir diesen Buffer bei einem file of Char selbst basteln, ausser du willst tatsächlich eine 13mb grosse Datei byteweise lesen...)
Amiga-Fan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 534



BeitragVerfasst: Fr 18.03.05 16:18 
Zitat:
ich würde das 2te da mal weg machen, und es mit einem file of char probieren.

stimmt denkfehler

jetzt scheints zu funktionieren:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
  
    QuellDatei:file of Byte;
    ZielDatei: file of byte;
    tmpChar:byte;
begin
  try
    AssignFile(QuellDatei,sFilePath+'Delete.sql');                // SQL-Statement ins Insert.sql Script schreiben
    Reset(QuellDatei);

    DeleteFile(sFilePath+'Delete2.sql');
    AssignFile(ZielDatei,sFilePath+'Delete2.sql');                // SQL-Statement ins Insert.sql Script schreiben
    Rewrite(ZielDatei);

    x:=filesize(QuellDatei)-1;
    while x>=0 do begin
      seek(Quelldatei,x);
      read(QuellDatei,tmpChar);
      dec(x);
      Write(ZielDatei,tmpChar);
    end;

    CloseFile(QuellDatei);
    CloseFile(ZielDatei);


Ergebnis:

;'632030000000-6400-5554-1000-66716000'=dItsiHetatSkooB erehw tsiHetatSkooB morf eteleD

;'314110000000-4400-5554-1000-66716000'=dIgnikooB erehw gnikooB morf eteleD

;'067500000000-3400-5554-1000-66716000'=dInoitcasnarTkooB erehw noitcasnarTkooB morf eteleD

Ach wenn man einen Spiegel dagegen hält klappt das schon :lol:
Ich werde das wohl so lassen und zeilenweise einlesen und das dann wieder umdrehen...

Danke für die Hilfe :)
JoachimQ
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 59


D2, D6 und D7
BeitragVerfasst: So 28.08.05 13:50 
user profile iconAmiga-Fan hat folgendes geschrieben:
Zitat:
ich würde das 2te da mal weg machen, und es mit einem file of char probieren.

stimmt denkfehler

jetzt scheints zu funktionieren:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
  
    QuellDatei:file of Byte;
    ZielDatei: file of byte;
    tmpChar:byte;
begin
  try
    AssignFile(QuellDatei,sFilePath+'Delete.sql');                // SQL-Statement ins Insert.sql Script schreiben
    Reset(QuellDatei);

    DeleteFile(sFilePath+'Delete2.sql');
    AssignFile(ZielDatei,sFilePath+'Delete2.sql');                // SQL-Statement ins Insert.sql Script schreiben
    Rewrite(ZielDatei);

    x:=filesize(QuellDatei)-1;
    while x>=0 do begin
      seek(Quelldatei,x);
      read(QuellDatei,tmpChar);
      dec(x);
      Write(ZielDatei,tmpChar);
    end;

    CloseFile(QuellDatei);
    CloseFile(ZielDatei);


Ergebnis:

;'632030000000-6400-5554-1000-66716000'=dItsiHetatSkooB erehw tsiHetatSkooB morf eteleD

;'314110000000-4400-5554-1000-66716000'=dIgnikooB erehw gnikooB morf eteleD

;'067500000000-3400-5554-1000-66716000'=dInoitcasnarTkooB erehw noitcasnarTkooB morf eteleD

Ach wenn man einen Spiegel dagegen hält klappt das schon :lol:
Ich werde das wohl so lassen und zeilenweise einlesen und das dann wieder umdrehen...

Danke für die Hilfe :)


DeleteFile(sFilePath+'Delete2.sql'); --> Ich würd vorher noch abfragen ob die Datei überhaupt existiert!!!
reptile
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 40



BeitragVerfasst: So 14.01.07 15:24 
sry dass ich den alten thread nochmal benutze aber der letzte satz da interessiert mich. kann mir jemand sagen wie das geht, also abfragen ob eine datei existiert? die suchfunktion bringt nur diesen einen thread ^^
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 14.01.07 15:35 
Ähh, dafür kannst du einen neuen Thread erstellen, dann haben alle was davon...