![]() |
BlockRead/Write: Buffergröße = Schnelligkeit?
Hallo,
mittels folgenden Code (Ausschnitt) kopier ich eine Datei:
Delphi-Quellcode:
den Buffer definier ich so (alle anderen Variablen sind für
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; meine Frage unwichtig):
Delphi-Quellcode:
Nun meine Frage:
Buffer: array[0..100000] of char;
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? |
Re: BlockRead/Write: Buffergröße = Schnelligkeit?
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 ( ![]() |
Re: BlockRead/Write: Buffergröße = Schnelligkeit?
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; |
Re: BlockRead/Write: Buffergröße = Schnelligkeit?
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:
Würd das so funktionieren? |
Re: BlockRead/Write: Buffergröße = Schnelligkeit?
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. |
Re: BlockRead/Write: Buffergröße = Schnelligkeit?
Zitat:
|
Re: BlockRead/Write: Buffergröße = Schnelligkeit?
wie würdest du es machen?
könntst mir da mal ein beispiel machen? |
Re: BlockRead/Write: Buffergröße = Schnelligkeit?
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. |
Re: BlockRead/Write: Buffergröße = Schnelligkeit?
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) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22: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