Autor Beitrag
night
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Sa 28.07.07 16:01 
HI, ist es möglich einfach eine beliebige Datei zu öffnen, zB Zeichenprogramm.exe und die dann in einem Memo in 01010101 ausgeben lassen?

Ich habe schon etwas gefunden, das aber leider nur komische Zeichen ausgibt und immermal eine Fehlermeldung herbeiruft :(
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TForm1.Button1Click(Sender: TObject);
var
  FS: TFileStream;
  Datei: String;
begin
  if OpenDialog.Execute then
  begin
    FS := TFileStream.Create(Opendialog1.FileName,fmOpenRead or fmShareDenyWrite);
    try
      SetLength(Datei,FS.Size);
      FS.Read(PChar(Datei)^,Length(Datei));
    finally
      FS.Free;
    end;
    Memo1.Lines.Add(Datei);
  end;
end;


Liebe Grüße night
Chryzler
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1097
Erhaltene Danke: 2



BeitragVerfasst: Sa 28.07.07 16:48 
Sicher ist das möglich.
ausblenden Delphi-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:
procedure TForm1.Button1Click(Sender: TObject);  
var  
  FS: TFileStream;  
  Datei: String;  
  b: Byte;
  s: array[0..7] of Char;
begin  
  if OpenDialog.Execute then  
  begin  
    FS := TFileStream.Create(Opendialog1.FileName, fmOpenRead or fmShareDenyWrite);  
    try  
      repeat
        FS.Read(b, 1);
        s[0] := Chr(Integer((b and $80) = 0));
        s[1] := Chr(Integer((b and $40) = 0));
        s[2] := Chr(Integer((b and $20) = 0));
        s[3] := Chr(Integer((b and $10) = 0));
        s[4] := Chr(Integer((b and $8) = 0));
        s[5] := Chr(Integer((b and $4) = 0));
        s[6] := Chr(Integer((b and $2) = 0));
        s[7] := Chr(Integer((b and $1) = 0));
        Memo1.Text := Memo1.Text + s;
      until FS.Position = FS.Size;  
    finally  
      FS.Free;  
    end;       
  end;  
end;

Habs nicht ausprobiert, könnte gehen, könnte auch sein, dass es komplett falsch ist. Einfacher gehts sicherlich auch. :P


Zuletzt bearbeitet von Chryzler am Do 23.08.07 11:22, insgesamt 2-mal bearbeitet
night Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: So 29.07.07 12:20 
Danke für deine Antwort, leider werden nur 4-eckige Kästchen ausgegeben.
Zur Verständnis, was bedeutet $10 etc.

Mfg night
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 29.07.07 12:47 
Ergänz in den Zeilen 14 bis 21 mal noch ein +48 vor der letzten schließenden Klammer.

Das $ vor einer Zahl steht für Hex-Schreibweise.

_________________
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.
Chryzler
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1097
Erhaltene Danke: 2



BeitragVerfasst: So 29.07.07 12:49 
So gehts.
ausblenden Delphi-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:
procedure TForm1.Button1Click(Sender: TObject);
var
  FS: TFileStream;
  buf: array of Byte;
  s: array[0..7] of Char;
  i: Integer;
begin
  if OpenDialog.Execute then
  begin
    FS := TFileStream.Create(Opendialog1.FileName, fmOpenRead or fmShareDenyWrite);
    SetLength(buf, FS.Size);
    try
      FS.Read(buf[0], FS.Size);
      for i := 0 to High(buf) do
      begin
        s[0] := Chr(Integer((buf[i] and $80) <> 0) + 48);
        s[1] := Chr(Integer((buf[i] and $40) <> 0) + 48);
        s[2] := Chr(Integer((buf[i] and $20) <> 0) + 48);
        s[3] := Chr(Integer((buf[i] and $10) <> 0) + 48);
        s[4] := Chr(Integer((buf[i] and $8) <> 0) + 48);
        s[5] := Chr(Integer((buf[i] and $4) <> 0) + 48);
        s[6] := Chr(Integer((buf[i] and $2) <> 0) + 48);
        s[7] := Chr(Integer((buf[i] and $1) <> 0) + 48);
        Memo1.Text := Memo1.Text + s;
      end;
    finally
      FS.Free;
    end;
  end;
end;

user profile iconBenBE hat folgendes geschrieben:
Ergänz in den Zeilen 14 bis 21 mal noch ein +48 vor der letzten schließenden Klammer.

Jep.
night Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: So 29.07.07 15:00 
Cool, danke es geht. Jetzt muss ichs nur noch verstehen.
Das ganze wird Byteweise ausgegeben und dann wird das Byte in Bits zerlegt.
$80 ist also im Dezimalsystem 128
$40 .. 64
$20 .. 32
$10 .. 16
$08 8
$04 4
$02 2
$01 1
Für was wird das benutzt.
Was genau passiert hier?
s[0] := Chr(Integer((buf[i] and $80) <> 0) + 48);
Und warum +48?
Chr() gibt das Zeichen zurück, das im Bytewert dem ASCIIwert entspricht.
Was macht denn Integer();
Sry das ich euch so löchere, aber ich möchte das auch gener verstehen.

Mfg night
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 29.07.07 15:13 
Integer(Ausdruck) ist ein expliziter Typecast, da Ausdruck <> 0 einen Boolean zurückgibt, man zum Rechnen aber einen Integer benötigt. Und da in Delphi False = 0 und True=1, ergibt sich der Rest relativ praktisch ;-)

Das +48 ist dafür da, damit man für False 48 ('0') und für True 49 ('1') erhält. Schnellere Variante als IntToStr ...

_________________
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.
Chryzler
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1097
Erhaltene Danke: 2



BeitragVerfasst: So 29.07.07 15:16 
Also.

Zuerst wird die ganze Datei in den Puffer buf eingelesen. s ist ein Char-Array, mit 8 Elementen. Jedes Byte hat ja so ungefähr 8 Bits. Die For-Schleife geht dann jedes Byte in der Datei durch und setzt jeweils die 8 Elemente von s entsprechend den Bits vom aktuellen Byte. Und das ist genau das, was folgende Zeile macht.
ausblenden Delphi-Quelltext
1:
s[0] := Chr(Integer((buf[i] and $80) <> 0) + 48);					

$80 sieht in binärer Form so aus: 10000000. buf[i] and $80 liefert nun 10000000 zurück, wenn in buf[i] das erste Bit gesetzt ist, ansonsten 00000000. Genauso ist es auch bei den anderen Bits. $40 ist in binärer Form 01000000. buf[i] and $80 gibt 01000000 zurück, wenn das zweite Bit gesetzt ist, ansonsten auch wieder 00000000. Dann überprüfe ich jedesmal, ob das Ergebnis nicht 00000000 ist. Denn dann ist das jeweilige Bit gesetzt. Integer() ist ein sog. Suche in der Entwickler-Ecke TYPECAST, er wandelt den Wert in der Klammer (hier Boolean) in einen Integer um. Jetzt sieht die Lage so aus: Wenn das jeweilige Bit gesetzt ist, dann bekommen wir den Wert 1, ansonsten den Wert 0, beidemale jedoch als Integer! Diesen Wert addieren wir jetzt zu 48, da das ASCII-Zeichen von 0 genau 48 ist, und von 1 natürlich 49. Mittels Chr() wandeln wir diesen Wert noch in einen Char um, der dann entweder '0' oder '1' ist. Das ganze geschieht mit allen 8 Bits von jedem Byte. Und dann wird einfach s, das nun die 8 Nullen oder Einsen enthält, ins Memo geschrieben.


Zuletzt bearbeitet von Chryzler am Do 23.08.07 11:23, insgesamt 1-mal bearbeitet
night Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: So 29.07.07 15:43 
Vielen Dank an euch! Hat mir super weiter geholfen! :D
Mfg night