Autor Beitrag
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 481

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Di 09.09.03 17:45 
Bisher hab ich Den Anfang einer Datei so ausgelesen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var buffer: array[0..99] of char;
begin
    AssignFile(F, filename);
    Reset(F,1);
    blockread(F,buffer,100);
    CloseFile(F); 
end;

Soweit klappt das. Ich möchte aber zur Laufzeit bestimmen, wieviel ich von der Datei lesen möchte. Das wollte ich mit
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
var buffer: array of char;
begin
    AssignFile(F, filename);
    Reset(F,1);
    setlength(buffer,200);
    blockread(F,buffer,200);
    CloseFile(F);
end;

machen, aber da gibts den Fehler "I/O Error 998".
Erstens finde ich keine Fehlerbeschreibung dafür und zweitens weiss ich nicht, was ich da falsch mache.
Wie gehts richtig? Danke schonmal.

_________________
We are, we were and will not be.
Brueggendiek
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 304

Win 98, Win98SE, Win XP Home
D5 Std
BeitragVerfasst: Di 09.09.03 19:42 
Hallo Gausi!

Bei mir kommt da "Anwendung wird wegen eines ungültigen Vorgangs geschlossen" - genauso nichtssagend.

Erklärung:
Bei einem dimensionierten (statischen) Array (array [0..99]) steht an der Adresse der Speichervariablen das erste Feldelement im Speicher, die anderen folgen im Gänsemarsch. Deshalb klappt der Blockread mit dimensionierten Arrays.

Bei einen dynamischen Array enthält die Array-Variable nur einen Pointer auf den Datenbereich (4 Byte groß) - diesen zu manipulieren ergibt wenig Sinn und führt zum Absturz, weil die nachfolgenden Speicherstellen überschrieben werden!

Das Ganze muß so geschrieben werden:
ausblenden Delphi-Quelltext
1:
    blockread(F,buffer[0],200);					

dann klappt's auch mit'm Blockread.

Die einzelnen Elemente des Arrays stehen nämlich nacheinander im Speicher, die Variable zeigt auf diese Anordnung. Ein solcher Zugriff darf also nicht auf die Variable erfolgen, sondern es muß das erste Element genommen werden.

Diese Schreibweise wäre auch bei einem statischen Array anwendbar - allerdings muß das nicht bei 0 beginnen!
ausblenden Delphi-Quelltext
1:
var buffer: array [10000..10099] of char;					

wäre z.B. auch zulässig!

Gruß

Dietmar Brüggendiek
Gausi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 481

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Di 09.09.03 20:17 
Wow, super Antwort! Habs ausprobiert, und es scheint zu klappen. Und ich glaube, ich habe jetzt auch verstanden, WARUM das so klappt und anders nicht. :D

_________________
We are, we were and will not be.
Bääääär
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 117



BeitragVerfasst: Sa 03.03.07 15:37 
ich habe ein ähnliches Problem, der Fehler ist zumindest bei mir der selbe.

pics ist ein dynamisches array of formate.bild. Und die datei eine typisierte.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
procedure readthumbnails();
var
i:integer;
f:file of formate.Tbild;
begin
setlength(pics,0);
if save_path<>'' then
  try
  assignfile(f,save_path);
  reset(f);
  i:=0;
  while not eof(f) do
    begin
      setlength(pics, length(pics));
      read(f,pics[i]);
      inc(i);
    end;
  except
  end;
closefile(f);
end;


Ich wüsste nicht, was ich da falsch mache, oder hat das auch wieder was mit dem dynamischen Array zu tun?
HelgeLange
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 735
Erhaltene Danke: 6

Windows 7
Delphi7 - Delphi XE
BeitragVerfasst: Sa 03.03.07 16:00 
das Problem liegt in deinem SetLength. Du musst das Array pics auf die Anzahl der Bilder in deinem File setzen.

warum machst Du jedesmal SetLength in der Schleife ? Reicht doch einmal. Innerhalb der Schleife nur dann, wenn Du sequentiell inkrementierst.

mach es doch so :

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
SetLength(Pics, 0);
While Not EoF(F) Do begin
  SetLength(pics, Length(Pics) + 1);
  Read(F, Pics[High(Pics)]);
end;


hab mir das eben schnell ausm hut gezaubert, hoffe es geht, habs ned probiert :)

_________________
"Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
Bääääär
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 117



BeitragVerfasst: Sa 03.03.07 16:07 
ist das array 0..10 groß, dann ist der rückgabewert do bekanntlich 11. also erhöhe ich jedesmal das array um einen eintrag. du würdest es um 2 erhöhen.