OK, dann halt zum Üben....
Im Prinzip wurde hier einfach nur ein "File Of Byte" weggekapselt, insofern ist das schon OK.
Auch wenn da TFileStream und Co. wohl eine bessere Alternative wären.
TByteStream ist wohl kein ganz guter Name, da es ja nicht von TStreams abgeleitet ist und sonst auch kein "Stream" intern verwendet wird, bzw. es auch nur irgendwas damit zu tun hat.
Wie wäre es TBytesFile?
Wieso wird bei Write der Puffer zum Schreiben übergeben? (Var-Parameter)
An dem Buffer soll doch nichts verändert werden.
Wozu brauchst du das BufSize?
Die länge steht doch schon im Array drin. (Length)
Einem Array-Parameter kann man zwar schön
statische Arrays über geben, oder ein idrekt definiertes Array (weiß jetzt nicht wie das heißt).
x.Write([1, 2, 3, 4]);
Delphi-Quellcode:
procedure Write(Buffer: array of byte); overload; // für statische Arrays und direkte Angaben
procedure Write(Buffer: TBytes); overload; // für dynamische Arrays
procedure Read(var Buffer: TBytes; Count: Longint); // nur für dynamische Arrays möglich
// oder
function Read(Count: Longint): TBytes; // ebenso
Was sind fail und done?
Wenn du kein
Delphi, sondern Lazarus/FPC verwendest, dann erwähn das bitte auch.
Aber dennoch ... wieso inherited Destroy eigentlich Done und nicht das übergeordnete Destroy?
Die Variable IResult kann weg, da du den Wert eh nur einmal auswertest und das gleich in der nächsten Zeile.
Was passiert, wenn Mode "ungültig" ist, also keinem deiner behandelten Werte entspricht?
Wieso "verwirfst" du quasi das IOResult?
Das gehört an fail übergeben, oder es sollte man sonstwie auswerten und weiterreichen .... und was macht fail eigentlich?
Der Grund, also IOResult, gehört, wenn möglich übersetzt, in die Fehlermeldung mit rein, damit man weiß warum es nicht ging.
Da du die Datei komplett kapselst, gehört auch die Fehlerbehandlung koplett da rein. (ja, IOResult könnte man extern eventuell noch abfragen, aber jenachdem was fail macht, könnte das dann schon ungültig sein)
Nochmal zu den "unnötigen" Variablen, wie vorhin schon das IResult.
Delphi-Quellcode:
function TByteStream.ReadByte: Byte;
begin
System.Read(FFile, Result);
end;
Da das Result von TByteStream.Read immer dem BufSize entspricht, ist es nutlos und es kann eine Prozedur werden.
TByteStream.Read(Buffer, BufSize) : entweder du nimmst die größe von Buffer (Length) oder den Wert von BufSize.
- bei BufSize wird der Buffer auf die "richtige" länge gebracht und nicht blind drin rumgeschrieben
- bei Length(Buffer) ist BufSize "nutzlos" und flieg raus, aus dem Code
Und wozu Read/Write das Current/FilePos brauchen, hab ich nicht verstanden, danie wirklich verwendet wird, außer es im Result wieder rauszurechnen ... hätte man bei 0 angefangen, bräuchte man es auch nicht rausrechnen, bzw. -0 ist ja nichts.
Warum macht Seek bei 2zwei Drittel des Codes Nichts? (CurrentPos und End)
Wenn du schon OpenRead und Open aka OpenReadWrite unterscheidest, dann gehort vor das Reset noch der richtige FileMode zugewiesen.
TReader ist ein blöder Name ... Was liest der denn und außerdem
TReader?
Wie wäre es mit TBytesReader, für das TBytesFile?
Und daß beim TReader in der Implementation der klassenname fehlt ist bestimmt nur schlimmes Copy&Paste.