AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi BlockRead/Write: Buffergröße = Schnelligkeit?
Thema durchsuchen
Ansicht
Themen-Optionen

BlockRead/Write: Buffergröße = Schnelligkeit?

Ein Thema von Helmi · begonnen am 26. Mär 2008 · letzter Beitrag vom 24. Apr 2008
Antwort Antwort
Benutzerbild von Helmi
Helmi

Registriert seit: 29. Dez 2003
Ort: Erding, Republik Bayern
3.312 Beiträge
 
Delphi XE2 Professional
 
#1

BlockRead/Write: Buffergröße = Schnelligkeit?

  Alt 26. Mär 2008, 15:15
Hallo,

mittels folgenden Code (Ausschnitt) kopier ich eine Datei:

Delphi-Quellcode:
while FileLength > 0 do
  begin
    BlockRead(FromF, Buffer[0], SizeOf(Buffer), NumRead);
    FileLength := FileLength - NumRead;

    BlockWrite(ToF, Buffer[0], NumRead);

    PB_Position := PB_Position + NumRead;
  end;
den Buffer definier ich so (alle anderen Variablen sind für
meine Frage unwichtig):

  Buffer: array[0..100000] of char; Nun meine Frage:
Ist meine Annahme richtig: Je größer der Array-Buffer,
desto schneller geht das kopieren?

Und falls ja, was ist das Maximum des Buffers?
(ich denke mal Arbeitsspeicher begrenzt die Größe)

bzw. Welche Größe sollte das Array sinnvollerweise haben?
mfg
Helmi

>> Theorie ist Wissen, dass nicht funktioniert - Praxis ist, wenn alles funktioniert und keiner weiss warum! <<
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#2

Re: BlockRead/Write: Buffergröße = Schnelligkeit?

  Alt 26. Mär 2008, 15:42
Wozu legst du dir eine solche grosse Struktur auf dem Stack an? Hast du zuviel davon? Alloziiere dynamisch Speicher dafür!

Und die Buffergröße hängt damit zusammen, aber zu große Buffergrößen können den Kopiervorgang auch wieder verlangsamen. Du könntest dich über die Clustergröße beim jeweiligen Laufwerk kundig machen, wenn du das optimieren willst, aber ansonsten sollte ein Buffer von vllt. 32 KB - 128 KB reichen.

Aber was mich noch viel mehr stört: Warum verwendest du die alten Pascal Dateiroutinen? Warum nutzt du keine Streams? Die machen das entsprechend für dich (Delphi-Referenz durchsuchenTStream.CopyFrom()) und vor allem sind sie viel besser geeignet als die veralteten Routinen.
  Mit Zitat antworten Zitat
devidespe

Registriert seit: 7. Sep 2006
Ort: Berlin
434 Beiträge
 
Delphi 10.4 Sydney
 
#3

Re: BlockRead/Write: Buffergröße = Schnelligkeit?

  Alt 26. Mär 2008, 16:01
TFileStream wäre der geeigntee Datentyp, mit dem man unter heutigen 32-Bit Umgebungen effizient Dateien kopiert. Die BlockWrite/BlockRead-Funktionen sind noch ein Relikt aus TurboPascal/BorlandPascal-Zeiten und quasi obsolete (sie werden also nur noch aus Kompatibilitätsgründen unterstützt).

So könnte ein entsprechender Quellcode inkl. Fehlermanagement aussehen:

Delphi-Quellcode:
VAR SourceFile : TFileStream;
    TargetFile : TFileStream;
BEGIN
  SourceFile:=TFileStream.Create('QUELLDATEI.TXT', fmOpenRead);
  TRY
    TRY
      TargetFile:=TFileStream.Create('ZIELDATEI.TXT', fmCreate OR fmShareDenyRead);
      TRY
        TargetFile.CopyFrom(SourceFile, SourceFile.Size);
      FINALLY
        FreeAndNil(TargetFile);
      END;
    FINALLY
      FreeAndNil(SourceFile);
    END;
  EXCEPT
    ShowMessage('Fehler aufgetreten.');
  END;
END;
Devid
  Mit Zitat antworten Zitat
Benutzerbild von Helmi
Helmi

Registriert seit: 29. Dez 2003
Ort: Erding, Republik Bayern
3.312 Beiträge
 
Delphi XE2 Professional
 
#4

Re: BlockRead/Write: Buffergröße = Schnelligkeit?

  Alt 26. Mär 2008, 16:04
Hallo Mütze,

danke für den Tip.

TStream.CopyFrom hab ich gar nicht gekannt - schaut ganz gut aus.

Hier mal ein kurzer Auszug aus der Hilfe zu CopyFrom:
Zitat:
CopyFrom kopiert die in Count angegebene Anzahl Bytes aus dem in Source angegebenen Stream in den Stream. Dann verschiebt es die aktuelle Position um die in Count angegebene Anzahl Bytes und gibt die Anzahl der kopierten Bytes zurück.
Da ich in einer ProgressBar den Kopierverlauf anzeigen lassen möchte, so könnt ich ja, wenn ich das richtig verstehe, das Count zufällig angeben (z. B. 1000) und dann in einer Schleife solange 1000 Byte kopieren lassen, bis die Datei fertig ist.
Würd das so funktionieren?
mfg
Helmi

>> Theorie ist Wissen, dass nicht funktioniert - Praxis ist, wenn alles funktioniert und keiner weiss warum! <<
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#5

Re: BlockRead/Write: Buffergröße = Schnelligkeit?

  Alt 26. Mär 2008, 18:33
Oder über die APIs CreateFile, GetFileSize, WriteFile / ReadFile, CloseHandle. Damit könntest du über GetFileSize die Größe der Zieldatei bestimmen und dann über GetMem dynamisch Speicher alloziieren. Wobei du natürlich auch hier Stückweise vorgehen kannst. (Über SetFilePointer kannst du die aktuelle Position ändern).

Oder wenns ganz simpel sein darf einfach CopyFile verwenden.
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#6

Re: BlockRead/Write: Buffergröße = Schnelligkeit?

  Alt 26. Mär 2008, 21:38
Zitat von Helmi:
Da ich in einer ProgressBar den Kopierverlauf anzeigen lassen möchte, so könnt ich ja, wenn ich das richtig verstehe, das Count zufällig angeben (z. B. 1000) und dann in einer Schleife solange 1000 Byte kopieren lassen, bis die Datei fertig ist.
Würd das so funktionieren?
Ja, würde es, aber es würde den Kopiervorgang auch wieder verlangsamen, da du es künstlich aufhälst mit der Aktualisierung der GUI und explizit den Vorgang in Einzelschritte aufteilst. Diese Aufteilung kann (bzw. wird wahrscheinlich sogar) ineffizienter sein als ein CopyFrom() ohne explizite Teilung.
  Mit Zitat antworten Zitat
Benutzerbild von Helmi
Helmi

Registriert seit: 29. Dez 2003
Ort: Erding, Republik Bayern
3.312 Beiträge
 
Delphi XE2 Professional
 
#7

Re: BlockRead/Write: Buffergröße = Schnelligkeit?

  Alt 26. Mär 2008, 21:43
wie würdest du es machen?

könntst mir da mal ein beispiel machen?
mfg
Helmi

>> Theorie ist Wissen, dass nicht funktioniert - Praxis ist, wenn alles funktioniert und keiner weiss warum! <<
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#8

Re: BlockRead/Write: Buffergröße = Schnelligkeit?

  Alt 26. Mär 2008, 22:07
Wenn ich Nutzer bin, dann will ich ein schnelles und sicheres Programm was sich möglichst intuitiv bedienen lässt. Von daher:

- Wenn es sich um mehrere Dateien handelt, dann bau den Progressbar über die Dateianzahl auf.
- Wenn es sich um eine Datei handelt, dann setze einfach nur Screen.Cursor auf crHourGlass und im Finally auf crDefault zurück
- Wenn es eine grosse Datei ist, dann nutze den Shell Kopierfunktion mit dem Callback und stelle die Progressbar über den Callback dar.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.149 Beiträge
 
Delphi 12 Athens
 
#9

Re: BlockRead/Write: Buffergröße = Schnelligkeit?

  Alt 24. Apr 2008, 19:16
wie schon erwähnt, wäre es hier besser auf die "alten" Pascal-Routinen zu verzichten,
dnn diese haben meißt eine Pufferung (also einen eigenen Ziwischenspeicher, über den alles umgeleitet wird)

und bei den sonstigen Funtionen/Klassen kommt immernoch die WindowsFileCache ins Spiel.

Tipp: mal bei den FileSplittern im Forum hier umsehn ... die sind ja auf "schnelles" und "optimales" Kopieren ausgelegt.
(auch mal zum Thema NonCached umsehn)

Aber Muetze1's Vorschläge zeigen die "einfachen" Lösungswege.

Bei Dateioperationen sind aber Puffergrößen in vielfachen 512 Byte zu empfehlen
(z.B. 8 KB, 16 KB ... bis "maximal" 64 KB)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:17 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz