Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Binärdatei schreiben und lesen? (https://www.delphipraxis.net/178579-binaerdatei-schreiben-und-lesen.html)

milos 15. Jan 2014 21:13

Binärdatei schreiben und lesen?
 
Hallo,

ich bin mir nicht sicher ob das jetz möglich ist, frage aber trotzdem mal nach ^^

Kann ich eine Datei nur mit Bitwerten abspeichern? Also ich mein jetzt um die Datei so klein wie möglich zu halten z.B. für ein Bildformat.

MfG

Aphton 15. Jan 2014 21:17

AW: Binärdatei schreiben und lesen?
 
Ja mit der einzigen Bedingung, dass die Bitanzahl kongruent 0 modulo 8 sein muss, denn die kleinste darstellbare Einheit ist ein Byte!

milos 15. Jan 2014 21:41

AW: Binärdatei schreiben und lesen?
 
Also heisst es ich speichere in Bytes?

Das erste Byte "01001011", das zweite "10010011", und so weiter?

Wie kann ich so etwas realisieren?

MfG

Aphton 15. Jan 2014 21:46

AW: Binärdatei schreiben und lesen?
 
Jup.

Indem du alle deine Bits in Bytes groupierst und diese dann wie gewohnt, in (d)eine Datei mit üblichen Methoden (recherchiere selbst; über die sufu lässt sich einiges finden) schreibst.

Das gruppieren ginge z.B. so:
Delphi-Quellcode:
type
  T8Bits = Array[0..7] of Boolean;

function bitsToByte(const Bits: T8Bits): Byte;
var
  i, j: Integer;
begin
  Result := 0;
  j := 1;
  for i := 0 to 7 do
  begin
    if Bits[i] then
      Result := Result or 1;
    j := j shl 1;
  end;
end;

Sir Rufo 15. Jan 2014 21:54

AW: Binärdatei schreiben und lesen?
 
BTW: Jede Datei besteht aus einer einfachen Folge von Bytes.
In keiner Datei wird z.B. Zeichen, Bilder gespeichert, sondern Bytes, die dann als Zeichen oder Bilder interpretiert werden. Diese Interpretationsvorschrift nennt man dann das Format der Datei ;)

Neutral General 15. Jan 2014 22:04

AW: Binärdatei schreiben und lesen?
 
Aphton du verwirrst ihn doch nur -.-

Ich denke er will einfach nur per TFilestream o.ä. Daten binär (statt in Textform) speichern.

milos 16. Jan 2014 00:46

AW: Binärdatei schreiben und lesen?
 
Ich glaube TFilestream ist das richtige, jedoch finde ich nirgends einen Weg wie ich es so lösen kann wie ich es brauche :/

Wie kann ich nun wirklich nur Byts reinschreiben? Sry wenn ich was übersehe aber finde es wirklich nirgends o_O

MfG

Popov 16. Jan 2014 01:09

AW: Binärdatei schreiben und lesen?
 
Vielleicht solltest du genauer schreiben was du willst, denn "ich will Bytes schreiben" ist etwas zu allgemein, denn selbst wenn du den Text "Hallo Welt!" in ein TMemo schreibst und es abspeicherst, schreibst du Bytes. Bytes schreiben ist also nichts ungewöhnliches.

Vielleicht suchst du aber auch nur das:

Delphi-Quellcode:
// Läd eine Datei und übergibt ihn als String
// sInFile = Name der Datei die geladen werden soll
// sFileString = VAR String - Datei als 8Bit String

function LoadStringFromFile(sInFile: String; var sFileString: AnsiString): Boolean;
var
  FileStream: TFileStream;
begin
  Result := False;
  if not FileExists(sInFile) then Exit;
  FileStream := TFileStream.Create(sInFile, fmOpenRead);
  try
    if FileStream.Size <> 0 then begin
      SetLength(sFileString, FileStream.Size);
      FileStream.Read(sFileString[1], FileStream.Size);
      Result := True;
    end;
  finally FileStream.Free end;
end;

// Speichert den 8 Bit String als Datei
// sOutFile = Name der Datei unter dem gespeichert werden soll
// sFileString = 8 Bit String

function SaveStringToFile(sOutFile: String; sFileString: AnsiString): Boolean;
var
  FileStream: TFileStream;
begin
  Result := False;
  FileStream := TFileStream.Create(sOutFile, fmCreate);
  try
    if Length(sFileString) <> 0 then begin
      FileStream.Write(sFileString[1], Length(sFileString));
      Result := True;
    end;
  finally FileStream.Free end;
end;
Das ist ein Code aus einem Programm von 2002, ich weiß also nicht ob es heute noch funktioniert.

Wie speicherst du dein Byte? Ganz einfach - erstelle ein AnsiString (AnsiStrings = 8 Bit; String = je nach dem). Das ist dann eine Kette von 8 Bit Bytes, auch wenn es sich String nennt.

Delphi-Quellcode:
var
  s: AnsiString;
begin
  s := s + #32 + #127 + #255;
  //oder
  s := s + Chr(32) + Chr(127) + Chr(255);

jfheins 16. Jan 2014 01:39

AW: Binärdatei schreiben und lesen?
 
Das erinnert mich ein wenig daran und daran :-)

milos 16. Jan 2014 03:13

AW: Binärdatei schreiben und lesen?
 
Ist mir irgendwie zu kompliziert xD Ich glaube ich benutze vorerst Textbasierte Dateien und probiere es später in Bytes zu lösen xD

MfG

Popov 16. Jan 2014 04:06

AW: Binärdatei schreiben und lesen?
 
Jetzt erzähle mir bitte was der Unterschied zwischen einer Textdatei und einer Binärdatei ist? Eigentlich keine. Theoretisch nutzt eine Textdatei nur die ersten sieben Bits eines Bytes. Das achte Bit wäre somit immer 0, weil ungenutzt. Theoretisch, oder nur früher, oder nur in USA. In Ländern wie Deutschland kommen zum Alphabet aber noch paar andere Zeichen dazu, die mit den ersten sieben Bits nicht abgedeckt sind, z. B. die Umlaute (siehe Ascii-Zeichensatz). Womit alle 8 Bit benutzt werden. Was ist also der Unterschied zwischen einer Textdatei und einer Binärdatei, wie z. B. einer Exe-Datei? Zuerst mal keiner (lassen wir mal den Uni-Code usw. zuerst außen vorweg), bis auf, dass wenn man eine Textdatei in einem Texteditor öffnet, dass Programm die Bytes in Ascii Zeichen darstellt. Auf der anderen Seite, öffnet man eine Exe Datei mit einem Texteditor, sieht man auch Ascii Zeichen.

Also, und ich hoffe hier kommt jetzt keiner mit einem UnicodeString an, besteht der normale String, soweit es ein AnsiString ist, von einer Aneinanderreihung von Bytes. Ein AnsiString ist eine Byte-Kette. Was das Byte zu bedeuten hat, ob es ein Befehl eines Programms oder eine Buchstabe ist, das hängt von der Deutung ab. Das ist wie mit einem VW-Transporter. Von außen gleich. Sind da acht Sitze drin, ist es ein Personen-Kleinbus, nimmt man die Sitze reaus, ist es ein Möbeltransporter. Das gleiche ist ein AnsiString. Eigentlich für Texte gedacht, man kann damit aber auch Binärdateien laden, z. B. Bilder.

Also, entweder du denkst zu kompliziert oder du kannst nicht erklären was du machen willst. Kleiner Tipp, guck dir an was eine Ascii Tabelle ist. Das ist eine Liste mit Werten zwischen 0 und 255, wobei jede zahl für etwas steht, meistens einen Buchstaben. Das ist aber nur eine Übersetzungstabelle, denn Werte zwischen 0 und 255 stehen für einen Byte. Womit es Binär wird.

Furtbichler 16. Jan 2014 07:01

AW: Binärdatei schreiben und lesen?
 
Also in meinen Dateien sind nur Daten. Keine Bytes, keine Zeichen, sondern Daten. Und noch genauer genommen bestehen sie (zumindest auf meiner Festpladde) aus winzigen Bereichen, die irgendwie magnetisiert sind, mir auch schnurz.

Daten also. Was das für Daten sind? Das kann man so und so sehen. Diese Daten müssen nämlich interpretiert werden. Die meisten machen das, indem Sie die Daten als Zahlen interpretieren und sich jeden einzelne Zahl vornehmen. Genausogut könnte man auch 16 Farben nehmen oder 3 Brotkrümel, oder die D-Tonleiter vollkommen egal. Es kommt auf die Interpretation an.

Nun sind Computer ziemlich Zahlenaffin, d.h. mit Farben, Musikalität und Optik haben sie es nicht so, aber im Zahlenschubsen sind sie ganz groß. Also verwenden wir den Zahlenraum 0..255 als Basisinterpretation der Daten. 0.255 deshalb, weil die Compis intern eigentlich nur Bitschubser sind und irgendwer sich mal gedacht hat, das das Gruppieren zu 8 Bits praktisch sein könnte. Es hätten auch 7 oder 9 sein können (Es waren sogar früher nur 7 und IBM hatte sogar mal 36 Bits in einem Computer, warum, wissen die wohl auch nicht mehr).
Gut gut. 8 Bits sind dann eine Zahl, ein Block. Oder ein Byte.
Auf jeden Fall sollten wir diese Bytes interpretieren, das ist vielleicht einfacher als die Magnetisierung auf der Pladde zu interpretieren. Ohne Interpretation hätten wir nur eine Suppe mit Zahlen, was ziemlich öde ist.

Also z.B. als Text, indem wir jeder Zahl einen Buchstaben zuordnen. Wir Europäer/Wessis sind da ziemlich ignorant und nehmen unsere Buchstaben, davon haben wir ja nicht zu viele. Dann noch Ziffern, ein Paar Sonderzeichen, Zeilentrenner, ein paar Spezialzeichen, die man nicht sieht, aber mit denen man etwas ausdrücken kann und -bupps- haben wir Texte. Als Interpretation.

Oder als Farbe. Dann hätten wir pro Byte eines von 256 Farben. Hmm. Bisserl wenig, aber reicht für's Erste. Meine Frau würde sich natürlich mal wieder aufregen, wie unrein ihre Haut ist, also... was machen wir? Wir mischen. Wir sagen: Das erste Byte ist der Rotanteil, der zweite der Gelb und der dritte der Blauanteil (oder in einer anderen Reihenfolge): Drei Bytes definieren also eine von -schießmichtot- Farben (256*256*256=16777216 um genau zu sein). Oder wir mischen mit anderen Farben (Lila, Hellblau, Gelb und Schwarz. Geht auch, gibt noch mehr Farben:4294967296).

Aber -hey- wie ist das mit Bildern? Bilder können gerastert werden, d.h. man legt ein Gitter drauf und definiert für jedes Karo eine Farbe. Damit man nicht zu viele Farben bekommt, nehmen wir entweder 256, 65536, 16777216 oder 4294967296. Danach 'entmischen' wir jede Farbe und erhalten so den Einzelanteil jeder Farbe, und das ist dann wieder ein jeweils Byte.

Ziemlich kompliziert, eigentlich. Jo, und deshalb macht das alles der Computer für uns. Wir sagen dem einfach: "Nimm dieses Bild, wandle die Farben als Rot/Gelb/Blau oder Cyan/Magenta/Yellow/Black um und speichere dann diesen Bytestrom ab.

Beim Einlesen lesen wir diese komischen Daten und sagen dem Computer: Das hier soll ein Bild sein, und zwar als RGB oder CMYK. Wupps, haben wir unser Bild. Wir könnten die Daten auch als Text interpretieren, aber das wäre dann ziemlicher Blödsinn (vermutlich).

Fazit: Daten sind nichts. Interpretation ist alles.

Aphton 16. Jan 2014 07:33

AW: Binärdatei schreiben und lesen?
 
Bzgl. letzten 2 Beiträgen - siehe hier

Popov 16. Jan 2014 13:32

AW: Binärdatei schreiben und lesen?
 
Aphton, du hast natürlich Recht, denn eine Textdatei ist genauso Binär gespeichert, wie ein Exe-Programm, wie ein Bild, wie eine MP3-Datei, wie ein AVI- oder MP4-Filmchen. Alles ist Binär, und ich kann eine Textdatei in einen AnsiString laden, wie ein Exe-Programm, wie eine Wav-Datei. Zuerst einmal sind alle Daten Binär, bzw. eine Aneinanderreihung von Bytes, ob Text oder was anderes.

Somit denke ich, dass der TE einfach nur zu kompliziert denkt. Er denk evtl. eine Textdatei ist anders gespeichert als eine Binärdatei.

Aber um noch mal auf die Frage des Unterschiedes zwischen Textdatei und Binärdatei zu kommen. Historisch gab es den mal, denn es gab eine Zeit in der es auf jeden Bit ankam. Und warum ein teures Bit kaufen und ungenutzt lassen, wenn man den nicht braucht. Und man brauchte früher das achte Bit nicht. Wozu? Haben die Amis Umlaute? Nein. Also, um es mit den Worten des großen amerikanischen Geschäftsmannes Bill Gates zu sagen, als im vorgeworfen wurde, dass Windows 1 oder 2 keine anderen Ländercodes beachtet, nur das amerikanische: "Windows ist ein amerikanisches Produkt, produziert in erster Linie für den amerikanischen Markt". Genauso dachten damals auch der Rest von Amerika: um einen Text darzustellen, reichen sieben Bits. Soweit ich mich erinnere ging die frühere Ascii-Tabelle auch nur bis 127. 128 bis 255 kam erst später (meiner Kenntnis und Erinnerung nach). Wobei ich nicht weiß ob die Nutzung des 8'ten Bits dem Standard entspricht, oder das nur Wildwuchs ist, so das Ascii immer noch aus 7-Bits besteht. Gibt man bei Google Ascii-Tabelle ein, bekommt man einen 8-Bit Zeichensatz. Allerdings muss ich zugeben, dass ich den Wechsel von 7 auf 8 Bit nicht mitbekommen habe. In meinem Kopf ist Ascii immer noch rein 7 Bit. Ich kann mich erinnern, dass die Erweiterung (also 8-Bit) dann Ansi-Tabelle genannt wurde. Die ging bis 255.

Es ist ja schön wenn man noch das DOS Zeitalter erlebt hat, denn man weiß, dass man früher (ich glaube Config.sys, kann aber auch Autoexec.bat gewesen sein) den für das Land gültigen Zeichencode laden musste. Hat man das nicht gemacht, war die amerikanische geladen und man hatte auf dem Zeichen ö (oder Ö?) den Doppelpunkt.

Ich kann mich aus dem Geschichtsuntersicht auch erinnern, dass es mal 5-Bit Systeme gab. Mit 32 Zahlen kann man auch das Alphabet darstellen. Aber bleiben wir mal bei den 7-Bits.

Natürlich gab es damals schon Programme, so dass man auch 8-Bit Speicher usw. gab. So gab es doch tatsächlich zwei Welten: eine 8-Bit und eine 7-Bit. Hat man nur Texte verschickt, reichten 7-Bit. Bei einem Text von 1000 Zeichen sparte man sich somit 1000 Bits. Bei der Übertragungsgeschwindigkeit von früher, konnte man so nicht nur Speicher sparen, sondern auch Zeit.

Kommen wir zurück zu Textdatei und Binärdatei. Wenn einer früher (also noch A. D.) zum mir sagte - diese Datei ist eine Textdatei - dann bestand sie vor meinem geistigen Auge durchaus aus einer Aneinanderreihung von Bytes, aber das achte Bit war eine Null. Heute ist das nicht so. Ich hab gerade eine TXT Datei mit einem Hex-Editor wie eine Binärdatei geöffnet und sehe da gelegentlich Doppel-Hexwerte die mit einem F beginnen, also ein Zeichen, dass das achte Bit genutzt wird.

Also, die Unterscheidung zwischen der Bezeichnung Textdatei und Binärdatei ist heute nur noch historisch. Wurde früher unter Binärdatei die Nutzung aller aller acht Bits verstanden und bei Textdatei die Nutzung von nur sieben Bits, nutzen heute auch Textdateien die vollen acht Bits. Womit sie nach früherer Sichtweise Binärdateien sind.

Und weil wir bei Ascii ist, bekanntlich sind die ersten 32 Zeichen Steuerzeichen. Und wer seine Briefe noch mit Edlin & Co schrieb, den kennt noch einige, wie z. B.
Delphi-Quellcode:
ShowMessage('Hallo' + ^j + 'Welt')
ergibt auch heute noch ein Zeilenumbruch. Und weil Null eigentlich nie ein richtiges Steuerzeichen war, terminieren wir heute damit unsere Zeichenketten. Somit hört der Text hier
Delphi-Quellcode:
ShowMessage('Hallo' + ^@ + 'Welt')
auch gleich nach Hallo auf.

Christian Seehase 16. Jan 2014 14:15

AW: Binärdatei schreiben und lesen?
 
Moin Zusammen,

ich entsinne mich noch, dass VisualSourceSafe die Unterscheidung Binär-/Textdatei durch das vorhanden sein einer binären 0 in der Datei festgelegt hat.
Keine binäre 0 enthalten => Textdatei.

p80286 16. Jan 2014 14:25

AW: Binärdatei schreiben und lesen?
 
Mannomann,
ist jetzt wieder Philosophie angesagt?
Der Binäre Weg ist der Weg ohne Interpretation der einzelnen Werte, also keine Steuerzeichen, kein UTF8,kein Longint, kein irgendwas, nur x00..xFF oder 2..255.

Zitat:

Zitat von milos (Beitrag 1243875)
Ich glaube TFilestream ist das richtige, jedoch finde ich nirgends einen Weg wie ich es so lösen kann wie ich es brauche :/

Wie kann ich nun wirklich nur Byts reinschreiben? Sry wenn ich was übersehe aber finde es wirklich nirgends o_O

MfG

Delphi-Quellcode:
mybuffer : byte;
wert    : byte;
geschrieben : longint;

mystream:=tfilestream.create(.....);

  mybuffer:=wert[i]
  geschrieben:=mystream.writebuffer(mybuffer,sizeof(mybuffer));
  if geschrieben<>sizeof(mybuffer) then Showmessage('Schreiben der Daten fehlgeschlagen);

mystream.free;
Das sollte als Grundgerüst erst einmal reichen. Vielleicht ist die OH auch noch hilfreich.
Ggf. könntest Du vllt. mit ein paar mehr Details heraus rücken.

Gruß
K-H

Gruß
K-H

sx2008 16. Jan 2014 15:08

AW: Binärdatei schreiben und lesen?
 
Wenn du ausschlieslich ein Array von Bits speichern möchtst dann könntest du meine
Delphi-Quellcode:
TBitStream
-Klasse benützen.
Z.Zt. fehlt noch das Laden der Bits aber das liese sich nachrüsten falls du Interesse hast.
Man kann die Bits nur seriell schreiben oder lesen; für wahlfreien Zugriff könnte man die Klasse TBits aus der VCL verwenden.
Delphi-Quellcode:
unit BitString;

interface

uses Classes;

type

  // verwaltet einen String der eine Liste von Bits repräsentiert
  TBitString = class(TObject)
    FData : AnsiString;
    FDataIdx : Integer;
    FDataBitpos: Integer;
    function GetCount:Integer;
  public
    function GetDataBit(var bit:Boolean):Boolean;
    procedure PutDataBit(bit:Boolean);
    procedure Reset;
    procedure SaveToStream(stream:TStream);
    procedure SaveToFile(const filename:string);

    property Data : AnsiString read FData write FData;
    property Count:Integer read GetCount;
  end;

implementation

{ TBitString }

function TBitString.GetCount: Integer;
begin
   Result := FDataIdx * 8 + FDataBitpos;
end;

function TBitString.GetDataBit(var bit: Boolean): Boolean;
begin
   bit := (ord(FData[FDataIdx]) and (1 shl FDataBitpos)) <> 0;

   Inc(FDataBitpos);
   if FDataBitpos >= 8 then
   begin
      FDataBitpos := 0;
      Inc(FDataIdx);
      Result := FDataIdx <= Length(FData);
   end
   else
      Result := True;
end;

procedure TBitString.PutDataBit(bit: Boolean);
begin
   if (FDataIdx = 1) and (FData = '') then
      FData := #0;

   if bit then
      FData[FDataIdx] := char(ord(FData[FDataIdx]) or (1 shl FDataBitpos))
   else
      FData[FDataIdx] := char(Ord(FData[FDataIdx]) and not (1 shl FDataBitpos));


   Inc(FDataBitpos);
   if FDataBitpos >= 8 then
   begin
      FDataBitpos := 0;
      Inc(FDataIdx);
      FData := FData + chr(0);
   end
end;

procedure TBitString.Reset;
begin
   FDataIdx := 1;
   FDataBitpos := 0;
   FData := '';
end;

procedure TBitString.SaveToStream(stream: TStream);
begin
   stream.WriteBuffer(Self.Data[1], Length(Data));
end;


procedure TBitString.SaveToFile(const filename: string);
var
  fs : TFileStream;
begin
   fs := TFileStream.Create(filename, fmCreate);
   try
      SaveToStream(fs);
   finally
      fs.Free;
   end;
end;


end.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:20 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz