| Autor |
Beitrag |
Flamefire
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Mi 14.03.07 06:42
Hi,
ich möchte eine Text-Datei bitweise auslesen. Oder genauer: 8-Bitweise und das ergebnis dann als Integer erhalten.
Gibts da eine methode dafür?
2.) ich möchte es genauso speichern, d.h. das ebn jede der 8 Bit ersetzt werden.
3.) kann es vl sein, wenn ich die datei mal 16-bitweise auslesen will, dass es kein vielfaches von 16-bit in der datei gibt? wenn ja, wie kann ich dann das letze paar mit 0en auffüllen bis die 16bit erreicht sind, oder macht der das automatisch?
Danke schonmal
|
|
Kroko
      
Beiträge: 1284
W98 W2k WXP
Turbo D
|
Verfasst: Mi 14.03.07 07:33
???
Jede Datei wird 8 bit weise gelesen und geschrieben!
Lies sie in einen Stream (TMemoryStream) und werte die Daten dann einzeln aus!
_________________ Die F1-Taste steht nicht unter Naturschutz und darf somit regelmäßig und oft benutzt werden! oder Wer lesen kann, ist klar im Vorteil!
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Mi 14.03.07 08:46
Hallo,
eine bisher noch normale Textdatei speichert den Text zeichenweise in einem Byte char = byte und bei unicode in 2 Bytes= 1 word.
Mit Funktion Ord(..Zeichen..{z.B.: String[PosImString]}) erhälst Du den Zugriff auf den byte-Wert eines Zeichens und kannst damit machen was Du möchtest (Bit Operatoren :AND XOR OR NOT ).
Die Funktion chr(ByteWert) wandelt den Wert wieder in ein Zeichen um.
Im Grunde genommen wird nichts umgewandelt.
Man teilt dem Compiler mit:
Jetzt will ich mit den Zeichen rechnen (geht ja mit Zeichen nicht) und danach die Zahlen sind jetzt als Zeichen zu betrachten.
Es findet also nur eine Typumwandlung statt, also nichts, was den Speicher ändert, sondern nur den Umgang damit(Ausgabe, rechnen 'A'+'B'char+char'A'+'B' = 'AB' oder byte+byte ..65+66=131)
Gruß Horst
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Mi 14.03.07 14:31
nein....nichzt ganz
es geht um RSA verschlüsselung...ich erhalte einen Integer (8Byte) den ich genauso abspeichern will, undnatürlich wieder lesen...
wenn ich den in einen char umwandle hätte ich ein prob: ascii ist ja nicht bis 65 tausend oder so ausgelegt
|
|
wulfskin
      
Beiträge: 1349
Erhaltene Danke: 1
Win XP
D5 Pers (SSL), D2005 Pro, C, C#
|
Verfasst: Mi 14.03.07 14:53
Hallo, so kannst du binär eine Datei einlesen: Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| var FileStream: TFileStream; B: Byte; S: ShortInt; begin FileStream := TFileStream.Create(DateiName, fmOpenRead or fmShareDenyWrite); try FileStream.Read(B, SizeOf(B)); FileStream.Read(S, SizeOf(S)); finally FileStream.Free; end; end; | Näheres siehe Hilfe oder Forum zu TFILESTREAM OR TSTREAM OR BINÄRE AND DATEI. Gruß Hape!
|
|
Backslash
      
Beiträge: 202
WIN XP
Delphi 5 Ent, Delphi 2005 Prof
|
Verfasst: Mi 14.03.07 14:55
1. Wenn du eine Dateigröße hast die ungerade ist, und du immer 2 Bytes auf einmal lesen oder schreiben möchtest, dann kannst du hier mit Ganzahldivision arbeiten.
Quelltext 1:
| AnzahlDatensätze := DateigrößeInBytes div DatensatzgrößeInBytes |
Die Anzahl der letzten Bytes berechnet sich wie folgt (über Modulo)
Quelltext 1:
| AnzahlLetzteBytes := DateigrößeInBytes mod DatensatzgrößeInBytes |
2. Um die entsprechenden 8 Bits bzw. das entsprechende Byte aus einem 8 Byte Integer auszulesen, habe ich hier eine Beispielfunktion, die du für denen Fall sicherlich noch anpassen kannst. Die holt das n-te Byte aus einem Int64-Wert raus. Die Funktion ist aus formellen Gründen einfach gehalten und zeigt das Prinzip. Möchtest du das erste Byte aus dem Int64 Wert (also die ersten 8 Bits) rausholen, rufst du GetByte mit Getbyte(Wert, 0) auf.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| function GetByte(Value : Int64; WhichByte : Integer) : Byte; var i : Integer; AndValue : Int64; TempValue : Int64; begin AndValue := $FF shl (8 * (WhichByte)); TempValue := 0; TempValue := AndValue AND Value; Result := TempValue shr (8 * (WhichByte)); end; |
So schreibst du einen kompletten Int64-Wert in den den Ausgabestream
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| var Bytewert : Int64; begin Bytewert := $FFFFFFFFFFFFFFFF; for i := 0 to 7 do Ausgangsstream.Write(GetByte(Bytewert, i)), SizeOf(Byte)); end; |
Ich hoffe ich konnte auch diesmal helfen. Das ganze soll lediglich als konkreten Ansatz dienen. Es steht dir frei den Code auf deine Wünsche anzupassen und zu verbessern.
Gruß
Backslash
Nachtrag: Die PutByte Funktion als Umkehrfunktion zum Schreiben des entsprechenden Bytes in einen Int64 darfst du gern selbst schreiben 
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Mi 14.03.07 15:10
ok hab jz das: 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:
| procedure TForm1.Button3Click(Sender: TObject); var n2,d2:longint;inputf,outputf:String;f,f2:Tfilestream;b:longint;ok:boolean; begin ok:=false; if input.Execute then begin inputf:=input.Filename; if output.Execute then begin outputf:=output.Filename; ok:=true; end; end; if(ok) then begin n2:=strtoint(Edit5.Text); d2:=strtoint(Edit6.Text); f:=TFileStream.Create(inputf,fmOpenRead); try f2:=TFileStream.Create(outputf,fmCreate); try while f.Position<f.Size do begin f.readbuffer(b,SizeOf(b)); b := encode(b,d2,n2); f2.writebuffer(b,SizeOf(b)); end; finally f.Free; end finally f2.Free; end; showmessage('Datei entschlüsselt!'); end; end; |
das geht auch...nur brauch er ewig =(
|
|
Backslash
      
Beiträge: 202
WIN XP
Delphi 5 Ent, Delphi 2005 Prof
|
Verfasst: Mi 14.03.07 15:19
Sag doch gleich dass du das so möchtest
Warum liest du die Datei nicht blockweise aus bzw. schreibst sie blockweise? Jeder Block kann ja dividiert durch SizeOf(LongInt) = 0 sein. Wenn du beispielsweise 256 Bytes, statt 8 oder gleich einen Megabyte in einen temporären Speicher einliest und diesen dann in der Schleife mit "encode" abarbeitest, dann sollte das einen argen Performancegewinn bringen 
|
|
Kroko
      
Beiträge: 1284
W98 W2k WXP
Turbo D
|
Verfasst: Mi 14.03.07 15:57
oder nimm TMemoryStream (s.o.)
_________________ Die F1-Taste steht nicht unter Naturschutz und darf somit regelmäßig und oft benutzt werden! oder Wer lesen kann, ist klar im Vorteil!
|
|
Backslash
      
Beiträge: 202
WIN XP
Delphi 5 Ent, Delphi 2005 Prof
|
Verfasst: Do 15.03.07 12:03
TMemorystream hat den Nachteil, dass der reservierte Speicher bei mir sehr schnell von Windows ausgelagert wird (habs unter win NT 4, Win 2000 und XP getestet). Dann wirds arg langsam, kann ich euch sagen. Daher verwendete ich NIE NIE NIE NIE (!!!) den Memorystream in solchen Fällen. Lieber einen TStream verwenden, weil es auch Dateien geben kann die 2 GB groß sind und dann? Hast du soviel RAM?
Einen temporären Puffer erstellst du mit:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| var TempBuf : PChar; begin GetMem(TempBuf, 1048576); [...] FreeMem(TempBuf); end; |
Nachtrag: Wenn du mit großen Puffern arbeitest, empfielt es sich Getmem in einen Try-Except Block zu packen und bei Except die Funktion mit einem Fehler "Zu wenig Arbeitsspeicher." zu verlassen.
|
|