Autor Beitrag
Trazom
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Do 14.02.08 10:28 
Guten Tach,

ich habe hier ein Array of Word, das sehr groß werden kann (bis zu 32.000.000) Einträge. Die Werte sollen direkt in eine Datei (File of Word) geschrieben werden, zur Zeit benutze ich eine Schleife:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
      AssignFile(datei, ('D:\MessungChannel' + IntToStr(channel)));
      Rewrite(datei);
      for i := 0 to (dataDesc.returnedSamplesPerSeg -1) do
      begin
            BlockWrite(datei, dataArray^[i], 1);  //Daten blockweise eintragen
      end;
      CloseFile(datei);


Das kann schon mal dauern und das ist schlecht. Gibt es eine Möglichkeit, das Array schneller in die Datei zu kriegen, vielleicht ohne jeden Eintrag einzeln nehmen zu müssen?

Danke für Eure Hilfe
jojo-sp
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 317

Windows XP Prof, Vista Ultimate & Home Premium, Windows 7
Delphi 7 Enterprise, Delphi 2009
BeitragVerfasst: Do 14.02.08 10:51 
Hallo,

Du musst dein Array schon durchlaufen, aber vielleicht versuchst du es mal mit einem Stream.
Lässt sich dan auch wieder realtiv einfach einlesen...

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:
28:
29:
30:
//--------------------------------------
// Speichern
procedure Tmain.SaveToFile;
var
  Stream: TFileStream;
  i: integer;
begin
  SaveToFile.FileName:= format('xyz_%s_ID%d',[ComboBoxText,MyID])

  if SaveToFile.Execute then
  begin
    UpdateMyRecord;
    
    if FileExists(SaveToFile.FileName) then
      DeleteFile(SaveToFile.FileName);
    try
      Stream := TFileStream.Create(SaveToFile.FileName, fmCreate);

      for i:= 1 to length(RecordArray) do
      begin
        if Assigned(Stream) then
          Stream.WriteBuffer(recordArray[i], SizeOf(TMyRecord));
      end;
    finally
      Stream.Free;
    end;
  end;
end;

// Fürs Lesen einfach den Teil von WriteBuffer durch "Stream.ReadBuffer(recordArray[i],SizeOf(TMyRecord));" ersetzen


Ich weiß aber nicht, ob das einen Geschwindigkeitsvorteil bringt!!!


Edit: Den Stream fürs Lesen natürlich auch anders erzeugen:

[/delphi][delphi] Stream:= TFileStream.Create(LoadFaultFile.FileName, fmOpenRead);

_________________
Ist der Ruf erst ruiniert, lebts sich gänzlich ungeniert...
Wilhelm Busch (1832 - 1908)
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: Do 14.02.08 11:00 
Wenn du ein einfaches Array of Word hast, dann sollte das auch so gehen:

ausblenden Delphi-Quelltext
1:
BlockWrite(datei, dataArray[0], SizeOf(Word) * Length(dataArray));					


Zumindest bei Streams kann man so ein Array auf einen Rutsch in eine Datei schreiben.

_________________
We are, we were and will not be.
Trazom Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Do 14.02.08 11:11 
[Monty Burns]Ausgezeichnet[/Monty Burns]

Das fetzt, danke schön.

Funktioniert das schnelle Einlesen in ein Array genauso?
Xong
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 113

WIN 2000
Borland Developer Studio 2006
BeitragVerfasst: Do 14.02.08 11:45 
user profile iconTrazom hat folgendes geschrieben:
[Monty Burns]Ausgezeichnet[/Monty Burns]Funktioniert das schnelle Einlesen in ein
Array genauso?

Sicher!
Es kann halt nur dauern, die Daten von der Festplatte in der Hauptspeicher zu schaufeln!

Verrätst du uns, wofür du 32 Millionen Einträge in einem Array brauchst? =)
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: Do 14.02.08 11:53 
Ja, das geht genauso. Allerdings musst du aufpassen, dass dein Array groß genug ist, d.h. man muss erst setlength aufrufen, und dann auslesen. Sonst überschreibst du unter Umständen andere Teile im Speicher und dein Programm stürtzt ab.

Wirklich lange sollte das auslesen nicht dauern. 64 MB sollten recht zügig gelesen sein ;-).

_________________
We are, we were and will not be.
jojo-sp
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 317

Windows XP Prof, Vista Ultimate & Home Premium, Windows 7
Delphi 7 Enterprise, Delphi 2009
BeitragVerfasst: Do 14.02.08 12:05 
Nur solltest du auf jeden Fall die länge des Arrays mit SetLength nur einmal bestimmen (vorrausgesetzt du nimmst ein dynamisches),
weil bei jedem SetLength wird für das komplette Array ein neuer Speicherbereich angefordert und nicht einfach angehängt, was bei der Dateigröße nicht unbedingt vorteilhaft ist. :-)

_________________
Ist der Ruf erst ruiniert, lebts sich gänzlich ungeniert...
Wilhelm Busch (1832 - 1908)
Trazom Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Do 14.02.08 12:32 
user profile iconXong hat folgendes geschrieben:
Verrätst du uns, wofür du 32 Millionen Einträge in einem Array brauchst? =)


Gern, ich programmiere hier die Software, mit der man auf eine Messkarte zugreifen kann. Das Teil liefert horrormäßige 8 Mrd. Samples pro Sekunde. 32 Mio. Samples kann es zwischenspeichern und die lese ich aus.

@die anderen:

So werde ich es machen, mit setlength. Ich werde auch immer .free aufrufen, bevor ich die Länge neu setze. Dann läuft der Speicher nicht über.

Vielen Dank nochmal.