Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi blockwrite sehr sehr große datei. (https://www.delphipraxis.net/107436-blockwrite-sehr-sehr-grosse-datei.html)

snow 27. Jan 2008 21:10


blockwrite sehr sehr große datei.
 
hallo

ich mach grad folgendes:

Delphi-Quellcode:
var
  Form1: TForm1;
  Num : Array of byte;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var dat : file;
lokal : integer;
begin
AssignFile(dat,'I:\delphi\testContainer\test1.dat');
rewrite(dat);
for lokal:=0 to 127 do Blockwrite(dat,num[0],1);
closefile(dat);
end;

procedure TForm1.FormCreate(Sender: TObject);
var lokal : integer;
begin
SetLength(Num,128);
for lokal:=0 to 127 do begin
num[lokal]:=lokal;
end;
end;
was ich machen will ist klar:

ich will das dynamische array am anfang mit den werten 0 bis 127 füllen, und dann den 1. wert 128 mal abspeichern.


soweit so gut.

klappt auch ohne error.

doch nun will ich nicht immer nur den ersten sondern alle werte abspeichern.

dazu habe ich

Delphi-Quellcode:
for lokal:=0 to 127 do Blockwrite(dat,num[lokal],1);
ausprobiert.

doch nun bekomme ich den E/A-Feherl 1784.

was soll den dass?

das array ist lang genug und eigendlich sollte es nix zu meckern geben.

Btw:

bei der 1. variante habe ich gemerkt, dass die datei, welche eigendlich grad mal 128byte groß sein sollte auf 14KB anwächst. nachdem ich mir die sache mit einem Hex-Viewer angeguggt habe stellte ich fest, dass 128byte packete mehrmals hintereinander in die datei geschrieben wurden.

Weis jemand weiter?

gruß snow

sirius 27. Jan 2008 21:27

Re: blockwrite sehr sehr große datei.
 
Wenn du byteweise schreibst müsste da glaub ich ein "rewrite(dat,1)" stehen

Hansa 27. Jan 2008 21:50

Re: blockwrite sehr sehr große datei.
 
Delphi-Quellcode:
Der ganze übertragene Block belegt höchstens Count * RecSize Bytes. RecSize ist die beim Öffnen der Datei angegebene Blockgröße (oder 128, falls keine Größe angegeben wurde).
Da steht aber ein SetLength von 128. Reicht das ? :zwinker:

himitsu 27. Jan 2008 21:50

Re: blockwrite sehr sehr große datei.
 
Rewrite(..., 1); ist per Standard definiert, also wäre es egel,

aber sicher, daß du genau for lokal:=0 to 127 do Blockwrite(dat,num[lokal],1); geschrieben hast
oder steht im Programm etwas anderes?

Du könntest es ja mal so versuchen, auch wenn ich nicht wüßte was dieses ändern sollte :gruebel:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var dat : file of byte;
lokal : integer;
begin
  AssignFile(dat,'I:\delphi\testContainer\test1.dat');
  rewrite(dat);
  for lokal:=0 to 127 do Blockwrite(dat,num[lokal],1);
  closefile(dat);
end;
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var dat : file of byte;
lokal : integer;
begin
  AssignFile(dat,'I:\delphi\testContainer\test1.dat');
  rewrite(dat);
  Blockwrite(dat,num[0],128);
  closefile(dat);
end;
Blos mal aus Interesse: was/wo ist denn da eine sehr große Datei?
(sehr groß fängt für mich so bei GB an)

sirius 27. Jan 2008 22:05

Re: blockwrite sehr sehr große datei.
 
Zitat:

Zitat von himitsu
Rewrite(..., 1); ist per Standard definiert, also wäre es egel,

Wie kommst du darauf? Schau mal einen Post über dich!

himitsu 27. Jan 2008 23:13

Re: blockwrite sehr sehr große datei.
 
hab den Post gesehn :zwinker:

Delphi-Quellcode:
var dat : file;
da hier keine Größe angegeben ist, wird per Default 1 verwendet.

Code:
var dat : file of [color=#ff0000]type[/color];
aber hier ist es per Default SizeOf(type)

Delphi-Quellcode:
type TNum : Array[0..127] of byte;

var dat : file of TNum;
also "nur" so wären es 128

[edit]grad getestet
Delphi-Quellcode:
function GetFileSize: Integer;
var F: File of Byte;
begin
  AssignFile(F, 'test1.dat');
  Reset(F);
    Result := FileSize(F);
  CloseFile(F);
end;

type TTest = array[0..31] of Byte;
  PFileRec = ^TFileRec;

var F1: File;
  F2: TextFile;
  F3: File of TTest;
  F4: File of Byte;
  F5: File;
  i, i1, i2, i3, i4, i5: Integer;
  l1a, l3a, l4a, l5a: Integer;
  l1b, l4b, l5b: Integer;
  Num: Array of Byte;

begin
  SetLength(Num, 32);

  //AssignFile(F1, 'test1.dat');
  //Rewrite(F1);
  //  i1 := PFileRec(@F1)^.RecSize;
  //CloseFile(F1);
  AssignFile(F1, 'test1.dat');
  Rewrite(F1);
    i1 := PFileRec(@F1)^.RecSize;
    Blockwrite(F1, num[0], 1{32? o.O});
  CloseFile(F1);
  l1a := GetFileSize;
  Rewrite(F1);
    for i := 0 to 31 do
      Blockwrite(F1, num[i], 1);
  CloseFile(F1);
  l1b := GetFileSize;

  //AssignFile(F2, 'test1.dat');
  //Rewrite(F2);
  //  i2 := PTextRec(@F2)^.RecSize;
  //CloseFile(F2);
  AssignFile(F2, 'test1.dat');
  Rewrite(F2);
    i2 := PFileRec(@F2)^.RecSize; //i2 := PTextRec(@F2)^.RecSize;
  CloseFile(F2);

  //AssignFile(F3, 'test1.dat');
  //Rewrite(F3);
  //  i3 := PFileRec(@F3)^.RecSize;
  //CloseFile(F3);
  AssignFile(F3, 'test1.dat');
  Rewrite(F3);
    i3 := PFileRec(@F3)^.RecSize;
    Blockwrite(F3, num[0], 1{1*TTest});
  CloseFile(F3);
  l3a := GetFileSize;

  //AssignFile(F4, 'test1.dat');
  //Rewrite(F4);
  //  i4 := PFileRec(@F4)^.RecSize;
  //CloseFile(F4);
  AssignFile(F4, 'test1.dat');
  Rewrite(F4);
    i4 := PFileRec(@F4)^.RecSize;
    Blockwrite(F4, num[0], 32);
  CloseFile(F4);
  l4a := GetFileSize;
  Rewrite(F4);
    for i := 0 to 31 do
      Blockwrite(F4, num[i], 1);
  CloseFile(F4);
  l4b := GetFileSize;

  //AssignFile(F5, 'test1.dat');
  //Rewrite(F5);
  //  i5 := PFileRec(@F5)^.RecSize;
  //CloseFile(F5);
  AssignFile(F5, 'test1.dat');
  Rewrite(F5, 1);
    i5 := PFileRec(@F5)^.RecSize;
    Blockwrite(F5, num[0], 32);
  CloseFile(F5);
  l5a := GetFileSize;
  Rewrite(F5, 1);
    for i := 0 to 31 do
      Blockwrite(F5, num[i], 1);
  CloseFile(F5);
  l5b := GetFileSize;

  Application.MessageBox(PChar(Format(
      'F1: File              = %d > %d %d'#13#10
    + 'F2: TextFile       = %d >    -        -'#13#10
    + 'F3: File of TTest =  %d >  %d      -'#13#10
    + 'F4: File of Byte  =    %d >  %d    %d'#13#10
    + 'F5: File(1)          =    %d >  %d    %d', [i1, l1a,
    l1b, i2, i3, l3a, i4, l4a, l4b, i5, l5a, l5b])), '');
end;
Zitat:

Zitat von Ergebnis
---------------------------

---------------------------
F1: File * * * * * * * = 128 > 128 4096
F2: TextFile * * * *= 128 > * * - * * * *-
F3: File of TTest = * 32 > * 32 * * * -
F4: File of Byte * = * * 1 > * 32 * * 32
F5: File(1) * * * * * = * * 1 > * 32 * * 32
---------------------------
OK
---------------------------

Variante = RecSize > Size_1x32 Size_32x1

aber, egal wie es da aussieht, sollte doch BlockWrite dennoch nur das schreiben, was man angegeben hat? :gruebel:
(kein Wunder daß ich da lieber mit der WinAPI arbeite)
nja, mal wieder eines der Probleme an den alten Pascal-Funktionen.
PS: es wird wohl nicht ohne Grund von "allen" empfohlen diese nicht mehr zu verwenden.
(viele empfehlen TFileStream und andere wenden sich direkt an Windows)

Aber meine Vermutung/Erklärung warum es 128 sind:
es liegt nicht an dem 128 Byte großem Array, dann davon weiß AssignFile definitiv überhaupt nichts.
die 128 kommen wohl daher, daß Delphi File indirekt wie TextFile mit einem Puffer ausstattet ist, welcher nunmal "rein zufällig" eine Größe von 128 Byte hat.
Delphi-Quellcode:
TTextBuf = array[0..127] of Char;
(drum hab ich bei obrigem Code/Test 32 Byte und nicht 128 verwendet, damit man den Unterschied sieht)

hab's aber grad selber nochma in der OH gefunden :shock:
Zitat:

Zitat von OH
Hinweis:
Wenn die Datei untypisiert deklariert ist und Sie beim Aufrufen von Reset keine Datenblockgröße angeben, nimmt FileSize eine Größe von 128 Bytes an. FileSize gibt also die Anzahl der Bytes geteilt durch 128 zurück.

ich würde dieses Verhalten ganz einfach als Fehler in Delphi ansehn, da hier 1 logischer gewesen wäre.

alzaimar 28. Jan 2008 06:23

Re: blockwrite sehr sehr große datei.
 
Der Fehler muss woanders liegen, denn das hier funktioniert:
Delphi-Quellcode:
Var
  dat: File;
  lokal: integer;
  Num : Array of byte;

Begin
  AssignFile(dat, 'C:\test1.dat');
  rewrite(dat);
  SEtLength (Num,128);
  For lokal := 0 To 127 Do
    Blockwrite(dat, num[lokal], 1);
  closefile(dat);
End;
Zitat:

Zitat von himitsu
ich würde dieses Verhalten ganz einfach als Fehler in Delphi ansehn, da hier 1 logischer gewesen wäre.

Es ist nicht gleich ein Fehler in Delphi, nur weil Du es als unlogisch ansiehst. Das BlockWrite ist älter als Du. Die 128 standen schon in der ersten Pascalversion, mit der ich gearbeitet habe (UCSD Pascal 1.0). Ob das in der Wirth'schen DEfinition auch schon enthalten ist, weiss ich nicht.
Soweit ich das beurteilen kann, stammen die 128 Bytes von der Sektorgröße damaliger Speicher (Tontafeln oder ? :gruebel: ). Das waren nun mal 'Blöcke' und mit diesem Superbefehl konnte man direkt auf die Tontafeln a.k.a. Floppies/Bänder schreiben! Also *hardwarenah* und supersauschnell! :zwinker:

Ich glaube, der Fragesteller hat uns noch nicht Alles verraten.

@snow: Reduziere dein Projekt mal auf die relevanten und fehlerhaften Zeilen und stelle es hier rein.

himitsu 28. Jan 2008 06:58

Re: blockwrite sehr sehr große datei.
 
Das BlockWrite, AssignFile und Co. sowas von uralt sind, seh ich schon ein
und nicht die 128 Byte "Cache" hab ich als Fehler angesehn,
sondern die tatsache daß bei Nichtangabe einer Größe diese 128 genommen werden.

Wenn nichts angegeben wird und Delphi oder damals Pascal dann eine 1 nehmen würden, dann würden solche Fehler hier nicht auftreten.

Zitat:

Zitat von alzaimar
Der Fehler muss woanders liegen, denn das hier funktioniert

sein Code entspricht F1 aus meinem Test und auch im Test kommt nirgends eine 32 Byte-Datei raus.

Wie es schon Vorgeschlagen wurde, muß er also nur bei Reset/Rewrite die 1 angeben oder mit File of Byte arbeiten ... also F4 oder F5.
und schon geht's.
Oder er steigt einfach auf FileStream's um (mit der WinAPI muß er sich ja nicht unbedingt überfordern :angel2: ).

Ich hatte (als ich noch diese Funktionen nutzte) wohl einfach nur Glück, da ich nie mit "File" arbeitete und dafür zufällig nur typisierte Dateien (File of) und Textdateien (TextFile) nutzte.

alzaimar 28. Jan 2008 07:18

Re: blockwrite sehr sehr große datei.
 
Ahoi himitsu san,
Das
Zitat:

Zitat von snow
doch nun bekomme ich den E/A-Fehler 1784.

hat mich stutzig gemacht. Und dieser Fehler tritt im Code von 'snow' so nicht auf. Da gibt es ein Problem mit dem 'Userbuffer'.

Ansonsten gilt wie immer (nicht für Dich): RTFM. Fehler dieser Art macht man genau deswegen, weil man eben nicht TFM liest. Ich habe BlockRead/Write ausschließlich für Dateikopierfunktionen verwendet (und als ich einmal eine kleine DB geschrieben habe).

Zitat:

Zitat von himitsu
sein Code entspricht F1 aus meinem Test und auch im Test kommt nirgends eine 32 Byte-Datei raus.

Wieso sollte eine 32 Byte Datei rauskommen? Ich würde eine 128 x 128 Byte große Datei annehmen, und genau das passiert. Denn in der OH steht es so beschrieben: Der optionale dritte Parameter gibt die Anzahl der *Records* an, die geschrieben werden.

himitsu 28. Jan 2008 07:41

Re: blockwrite sehr sehr große datei.
 
Zitat:

Zitat von alzaimar
Ahoi himitsu san,
Das
Zitat:

Zitat von snow
doch nun bekomme ich den E/A-Fehler 1784.

hat mich stutzig gemacht. Und dieser Fehler tritt im Code von 'snow' so nicht auf. Da gibt es ein Problem mit dem 'Userbuffer'.

jupp ... drum hab ich bei F3 auch keine 2 "Messwerte", da ich dort wegen diesem Fehler einfach das Nichtfunktioniernde weggelassen hab. :stupid:

32 ... nja, er hat eine 128 Byte-Array und das ist rein zufällig genausogroß wie der Datei-Puffer.
also nahm ich einfach irgendeinen anderen Wert (32 is doch 'ne nette Zahl :love: ), damit man nicht mit den 128-Byte des Puffers und den 128 Byte des Arrays durcheinander kommt.

denn wie soll man denn da wissen wovon die gemessenen 128 Byte nun stammen (Puffer oder Array).

[s]
Zitat:

Zitat von alzaimar
Der optionale dritte Parameter gibt die Anzahl der *Records* an, die geschrieben werden.

Größe eines Records :zwinker:[s/]

nja und wenn man nichts angibt, dann hätte sich als Default eigentlich die kleines Einheit (also 1 Byte) gut gemacht ... und nicht 'ne willkürliche 128

tja und da sein Array 128 Byte groß ist, hat e wohl das Problem aus meiner F3 bei sich vorliegen (obwohl er wohl nach F1 geschrieben hat ... bei 128 stimmt F1 mit F3 zufällig überein :? )

alzaimar 28. Jan 2008 07:51

Re: blockwrite sehr sehr große datei.
 
Zitat:

Zitat von himitsu
Zitat:

Zitat von alzaimar
Der optionale dritte Parameter gibt die Anzahl der *Records* an, die geschrieben werden.

Größe eines Records :zwinker:

Anzahl :stupid: RTM.
Zitat:

Zitat von Die Delphi OH
procedure BlockWrite(var f: File; var Buf; Count: Integer [; var AmtTransferred: Integer]);
Description
BlockWrite writes Count or fewer records to the file F from memory,...

Das es aus heutiger Sicht merkwürdig ist, keine Frage. Aber der Befehl stammt nun mal aus dem Mittelalter, was soll man machen.

himitsu 28. Jan 2008 07:55

Re: blockwrite sehr sehr große datei.
 
ups ja ... BlockWrite :wall:
der optionale Zweite bei Reset/Rewrite war die Recordgröße :oops:

taaktaak 28. Jan 2008 08:33

Re: blockwrite sehr sehr große datei.
 
Moin, Moin.

Interessant, was man in diesem Thread so alles über BlockWrite erfährt - obwohl ich es seit 25 Jahren verwende. Allerdings (natürlich) nicht in der vorgestellten Anwendungssituation; hier wäre eine typisierte Datei sicherlich angebrachter.

Eines fällt mir dabei auf: Es fehlt in den Beispielen die obligatorische Fehlerprüfung mit IOresult! Wenn schon Steinzeitprogrammierung, dann bitte reset/rewrite mit {$I-} und {$I+} "einrahmen" - das haben wir doch wohl so gelernt und es gehört zum richtigen "Steinzeit-Feeling" unbedingt dazu, oder etwa nicht? :roll:

Gruß Ralph

alzaimar 28. Jan 2008 08:37

Re: blockwrite sehr sehr große datei.
 
Quatsch :mrgreen: Der wahre Programmierer schert sich einen Dreck um korrekte Fehlerbehandlung! Profis programmieren ohne Netz und doppelten Boden und lassen die Anwendung gegen die Wand fahren. Nur so bekommt man ohne Mehraufwand aussagekräftige Fehlermeldungen, die nur der Programmierer versteht. Das verschafft Respekt und Ansehen! :freak:

taaktaak 28. Jan 2008 08:45

Re: blockwrite sehr sehr große datei.
 
:hello: na, ist was dran, in der Steinzeit hat man das alles nicht so eng gesehen und die Anwender waren auch etwas robuster und schmerzunempfindlicher ... :stupid:

snow 28. Jan 2008 13:10

Re: blockwrite sehr sehr große datei.
 
Delphi-Quellcode:
var
  Form1: TForm1;
  Num : Array of byte;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var dat : file;
lokal : integer;
begin
AssignFile(dat,'I:\delphi\testContainer\test1.dat');
rewrite(dat);
Blockwrite(dat,num[0],1);
closefile(dat);
end;

procedure TForm1.FormCreate(Sender: TObject);
var lokal : integer;
begin
setlength(num,128);
for lokal:=0 to 127 do begin
num[lokal]:=lokal;
end;
end;
so klappt es.

ich kann nun den gesammten array inhalt speichern.

naja anscheinend muss ich bei blockwrite immer 128 byte schreiben. Dies wäre natürlich verschwendung. via move in ein 128byte langes array zu schreiben. wenn ich nun z.b einen int32 10 bytes und einen 6 stelligen string(7bytes) abspeichern will,

schiebe ich zuerst den integer in array[0..3],
dann die 10 bytes in array[4..13],
dann den string in array[14..20]

im inhaltsverzeichniss der datei gebe ich dann nicht die blocknummer sondern die byte nummer an.

Diese wird durch 128 geteilt und der rest sollte die bytenummer im block angeben.

ich mach mich mal ran

gruß snow

himitsu 28. Jan 2008 14:46

Re: blockwrite sehr sehr große datei.
 
Siehe mein Test:

du muß nur beim Öffnen der Datei eine Größe oder einen passenden Typ angeben:
Delphi-Quellcode:
var dat : File of Byte;
Rewrite(dat);

// oder

var dat : file;
Rewrite(dat, 1);

alzaimar 29. Jan 2008 05:58

Re: blockwrite sehr sehr große datei.
 
@snow: Verwende doch Streams. BlockRead/BlockWrite sind veraltet (stand vorher schon irgendwo). Wirklich, halte Dich nicht mit diesen ollen Kamellen auf. Du musst Dich doch eh einarbeiten, da wäre es doch sinnvoll, es gleich mit den richtigen Werkzeugen zu tun. Und das sind nun mal Streams.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:50 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz