| Autor |
Beitrag |
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Do 28.04.05 22:14
512 Bytes ist genau ein logischer Sektor auf der Festplatte (ein physikalischer Sektor sind 520 IIRC), aber Windows liest generell ganze Sektoren von der Festplatte. Wenn Du also immer 512 Bytes (oder Vielfache) liest, bleibst Du immer genau am Anfang eines Sektors und Windows muss die Lesezugriffe nicht aufspalten, d.h. weniger Lesezugriffe --> Schnellerer Zugriff.
@Puffer: String[1024] kann nicht gehen, da es einen ShortString definieren würde und diese sind auf 256 Bytes begrenzt.
Definiere statt dessen einen ReadedString: Array [0..1023] of Char, Basisindex ist dann Index 0.
BTW: Es müsste eigentlic ReadString heißen, da Read in allen drei Formen gleich bleibt.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Fr 29.04.05 19:59
Wie soll ich das realisieren das er gleich 512 Bytes ausliest?
Den Quelltext von jasocoul versteh ich irgendwie nicht ganz. Was bedeutet zum Beispiel seek? Und warum ist seine Variante schneller? Er liest die Bytes auch ja einzel aus. Oder sollte ich es lieber mit TFileStream versuchen?
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Fr 29.04.05 20:15
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Fr 29.04.05 20:20
Normalerweise arbeite ich ja mit TFileStream. Es gab nur einen Grund warum ich ihn hier nicht verwendet hatte. Gibt es dort z.B. den Befehl eof? Und ich habe es auch nicht verwendet, da ich sonst immer nur bekannte Formate auslese, und nicht unbekannte.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Fr 29.04.05 20:24
Direkt als Abfrage gibt es in Streams den EOF-Befehl nicht, aber Du kannst Dir mit FS.Position >= FS.Size den EOF-Befehl ganz leicht nachbauen.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Fr 29.04.05 20:26
Und ist es egal ob ich FileStream.Free nehme oder FreeAndNil(FileStream)?
Und woran erkenne ich wieviel Bytes im letzten Sektor für mich wirklich von Bedeutung sind? Denn es kann ja sein, dass ich nur 10 Bytes vom letzten Sektor benötige. Oder muss ich das mit modulo selber herausfinden?
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Fr 29.04.05 20:32
Heiko hat folgendes geschrieben: | | Und ist es egal ob ich FileStream.Free nehme oder FreeAndNil(FileStream)? |
Eigentlich ja, es gibt nur einen bedeutenden Vorteil von FreeAndNil: Die Referenz auf das Objekt wird auch gleich gelöscht, womit der Aufruf von Assigned korrekt False ergibt. Das Manuelle auf Nil setzen entfällt somit.
Heiko hat folgendes geschrieben: | | Und woran erkenne ich wieviel Bytes im letzten Sektor für mich wirklich von Bedeutung sind? Denn es kann ja sein, dass ich nur 10 Bytes vom letzten Sektor benötige. Oder muss ich das mit modulo selber herausfinden? |
Nein, brauchst Du nicht.
Wenn Du mit FS.Read anstatt mit FS.ReadBuffer arbeitest, werden nur soviele Bytes zurückgegeben, wie tatsächlich vorhanden sind. Dass nur 10 Bytes gelesen wurden, gibt die Funktion dann als Result zurück.
Delphi-Quelltext 1:
| ReadSize := FS.Read(Puffer[0], 512); |
Der Rest (ab dem 11. Byte) ist dann aber undefiniert.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Sa 30.04.05 10:20
thx,
das Auslesen braucht jetzt mit FileStream nur halbe Sekunde, anstatt 10 Minuten mit der alten Variante  .
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Sa 30.04.05 10:39
Für 523 MB braucht meiner nur 15 Sekunden  !! Ich möcte nicht wissen, wie lange der mit meiner ertsne Variante gebraucht hätte. Eine Woche? Spielt jetzt aber keine Rolle mehr.
Aso es scheint egal zu sein, ob man nun 1024 oder 2048 mit einmal ausliest. Man macht kein sichtbaren Gewinn mehr. Es lohnt sich aber statt 512 1024 zu nehmen.
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Mo 02.05.05 17:08
Also irgendwie liest der nicht das ein was ich will  :
Quelltext 1: 2: 3:
| NY@ÞÏk|ž+ñ–‚+£fûËœh—èR@#: ÏQ™uÊ ßåúíhþ¯ÓÜ/aÁ©éjíá&M±^êØio¶ˆ*¾Í»[é¾%(ÙJeDؘað?ÏÂ’$œ‰— {ßErÝGŠëÀ…"gØ4lö·îP8Ë´I¿p‹l=œ"¬t²“1lMQ[oçb÷ßÁz‘¨È…ñ'‡¡¼}? 5ç 9âLnýwÒè>Ù”„¯ |
Das sollte eigentlich alle 256 ASCII-Code-Zeichen sein. Ich glaube nicht, dass die das sind.
Hier der 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: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57:
| procedure Kompression(const DateiFileStream: TFileStream; FileStr: String); var i: Cardinal; SignCounter: array[0..255] of Cardinal; ReadBuffer: array[0..511] of Byte; ReadSize: Word; TakeSign: array of Byte; KompFileStream: TfileStream; begin for i:=0 to 255 do begin SignCounter[i]:=0; end; while DateiFileStream.Position<DateiFileStream.Size do begin ReadSize:=DateiFileStream.Read(ReadBuffer[0], 512); for i:=0 to ReadSize-1 do begin inc(SignCounter[ReadBuffer[i]]) end end; KompFileStream:=TFileStream.Create(Copy(FileStr, 1, length(FileStr)-length(ExtractFileExt(FileStr)))+'.pck', fmCreate or fmOpenWrite or fmShareDenyWrite); for i:=0 to 255 do begin if SignCounter[i]>0 then begin SetLength(TakeSign, High(TakeSign)+2); TakeSign[High(TakeSign)]:=SignCounter[i]; KompFileStream.WriteBuffer(SignCounter[i], 1) end end; FreeAndNil(KompFileStream); end;
procedure TForm1.Button1Click(Sender: TObject); var DateiFileStream: TFileStream; OpenDialog: TOpenDialog; begin OpenDialog:=TOpenDialog.Create(Self); if OpenDialog.Execute then begin DateiFileStream:=TFileStream.Create(OpenDialog.FileName, fmOpenRead or fmShareDenyWrite); if DateiFileStream.Size<=4294967295 then begin Kompression(DateiFileStream, OpenDialog.FileName); end else begin Application.MessageBox('Die ausgewählte Datei ist für diese Version zu groß!', 'Datei zu Groß', 16) end; FreeAndNil(DateiFileStream); end end; |
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Di 03.05.05 10:56
Ok ich habe den Fehler gefunden. Hier die Lösung.
|
|
KidPaddle
      
Beiträge: 351
WinXP,Linux
D7 Prof, XE7
|
Verfasst: Di 03.05.05 12:57
Ich würde den Code wie folgt ändern. Der Code könnte noch optimiert und eine verbesserte Fehlerprüfung müßte noch eingebaut werden.
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: 31: 32: 33: 34: 35: 36: 37: 38: 39:
| procedure TForm1.Button1Click(Sender: TObject); var DateiFile: TextFile; ReadedString: array[0..1023] of Byte; <--- Datentyp geaendert iBytesRead : Integer; ReadedByte: Byte; <---- Neu i, j: Cardinal; SignCounter: array[0..255] of Cardinal; begin if GetFileSizeEx('WMEncoder.exe')<=4294967295 then begin for i:=0 to 255 do begin SignCounter[i]:=0; end; AssignFile(DateiFile, 'WMEncoder.exe'); Reset(DateiFile); while not eof(DateiFile) do begin iBytesRead := Read(DateiFile, ReadedString); if (iBytesRead > 0) then begin for j:= 0 to (iBytesRead - 1) do begin ReadedByte:=ReadedString[j]; inc(SignCounter[ReadedByte]) end end; end; CloseFile(DateiFile); for i:=0 to 255 do begin ShowMessage(IntToStr(i)+': '+IntToStr(SignCounter[i])); end; end else begin Application.MessageBox('Die ausgewählte Datei ist für diese Version zu groß!', 'Datei zu Groß', 16) end; end; |
Gruß
KidPaddle
|
|
|