Einzelnen Beitrag anzeigen

Muetze1
(Gast)

n/a Beiträge
 
#8

Re: [C++] Binärdateien

  Alt 31. Okt 2007, 14:40
Zitat von Mark90:
in delphi hatte ich für das speichern von records typisierte dateien verwendet. -> typisierte dateien sind ja nicht das gleiche wie binäre dateien?
Jain, doch, irgendwie sind sie schon recht ähnlich. Aber der Reihe nach.

Typisierte Dateien aus der Pascal Zeit sind nichts anderes, als eine feste Verbändelung einer Struktur und einer Datei. Dabei sagt dieses Konstrukt nur aus: Die Datei ist eine aneinander-Reihung von dieser Struktur. Dadurch rechnen alle Dateiroutinen automatisch diese Struktur in ihren Operationen ein. D.h. Jeder Lesevorgang liest automatisch SizeOf(Struktur) Bytes (also immer soviel Bytes wie die Struktur gross ist) und beim Schreiben gleiches. FileSize() liefert dir die Anzahl, wie oft die Struktur ganz in die Datei reinpasst (also eigentlich: wirkliche Dateigrösse div SizeOf(Struktur) ).

Wenn du nun eine Struktur definierst, welche wie deine C struct aussieht, dann hättest du das gleiche Problem:

Delphi-Quellcode:
type
  TMyFileStruct = Record
    name: string;
    strasse: string;
  end;

var
  MyFile: file of TMyFileStruct;
Mal abgesehen das dich Delphi schon warnt, dass der Typ "file of TMyFileStruct" eine Initialisierung braucht, wirst du hier auf das gleiche Problem stossen wie beim C++Builder: er würde nur 8 Bytes pro Eintrag schreiben und darin sind nur die Adressen der Strings und nicht deren Inhalt. String ist ein Synonym für AnsiString (so lange nicht explizit durch Compileroptionen umgestellt).

Bei C++ gibt es erstmal solche typisierten Dateitypen nicht (nicht grundsätzllich: Mit templates gibs bestimmt auch schon eine Lösung). Du nutzt ja nun in C++ nun die Streams und das kannst du eigentlich mit TFileStream in Delphi vergleichen (mal abgesehen, dass du direkt TFileStream unter dem C++Builder verwenden kannst und sogar direkt eine Delphi Unit einbinden kannst, welcher z.B. den entsprechenden Code enthält. Dann hättest du eine Unit zum Laden und Speichern und der Code wäre im C++Builder Projekt der gleiche wie im Delphi Projekt). Du versuchst nun die Struktur zu Lesen bzw. zu Schreiben. Hier hast du das gleiche Problem wie in Delphi: Die Dateistruktur muss feststehen.

Du hast bestimmt früher in Delphi folgendes Konstrukt verwendet:

Delphi-Quellcode:
type
  TMyFileStruct = Record
    name: shortstring; // bzw. string[x]
    strasse: shortstring;
  end;

var
  MyFile: file of TMyFileStruct;
Damit hast du die Strings von der Länge festgelegt (ShortString = 255 + Längenbyte). Damit war der Record auch 512 Bytes gross - egal wieviel Zeichen im Endeffekt von den Zeichenketten genutzt wurden. Dafür hast du aber auch den Nachteil: Name und Straße kann niemals mehr als 255 Zeichen lang sein. String, AnsiString etc. sind dynamisch und deshalb intern Zeiger auf den Inhalt, welcher sich dann dynamisch anpasst. Damit sind diese Zeichenketten nicht mehr an 255 Zeichen gebunden (im Gegenteil: sie können bis zu 2 GB lang werden).

Nun musst du dich aber darum kümmern, dass die Länge der Zeichenkette in die Datei geschrieben wird und dann entsprechend die Zeichen hinten ran. Dies habe ich C++ oben schon versucht zu implementieren.

Alternativ: Wenn du sagst, dass Name und Straße niemals mehr als 255 Zeichen lang werden, dann definier eine struct, welche Strings mit einer festen länge enthält (siehe ShortString bzw. string[] in Delphi):

Code:
struct info
{
   char Name[256];
   char Strasse[256];
};
Dann könntest du sogar ohne weiteres deine originalen Routinen verwenden und direkt mit den read() und write() Methoden die Struktur ein- und auslesen. Damit treten wieder die vorher genannten Einschränkung in Kraft (Zeichenkettenlänge), aber es würde funktionieren.

Tutorials kann ich dir keine nennen. Ich kann keine Schreiben, da ich schlecht erklären kann und selber habe ich keine gross gelesen, da Auto-Didakt.
  Mit Zitat antworten Zitat