Twitter und Facebook-Anbindung
X
Tweet Follow @twitterapi
!!! Anbindung an twitter und facebook öffnen !!!

Wenn Ihnen mein Online-Buch gefällt,
dann bedanken Sie sich doch mit einer kleinen Spende...

13.3.2 Binärdateien mit Streams

13.3.2 Binärdateien mit Streams

Nun werde ich noch abschließend zeigen, wie man eben gezeigten Quelltext mit Streams realisieren kann. Ich werde dabei den gleichen Datentyp benutzen wie eben.

 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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
					
char*		pcstrFileName		= "C:\\Test.bin";
bool		bGoOn			= true;

std::ofstream	oOutFileStream(pcstrFileName, std::ios_base::binary);

// Wenn die Dateien geöffnet werden konnten
if (oOutFileStream.is_open()) {
	try {
		printf("== Eingabe ========================\n");

		// Solange Personen hinzugefügt werden sollen
		while (bGoOn) {
			SPerson sPerson;
			char	cSign;

			printf("Vorname:  ");
			fflush(stdin);
			scanf("%s", &(sPerson.astrVorname));
			
			printf("Nachname: ");
			fflush(stdin);
			scanf("%s", &(sPerson.astrNachname));
			
			printf("Alter:    ");
			scanf("%i", &(sPerson.iAlter));
			
			printf("Gewicht   ");
			scanf("%f", &(sPerson.fGewicht));

			try {
				oOutFileStream.write((char*)&sPerson, sizeof(SPerson));
			} catch(...) {
				printf("Beim Speichern ist ein Fehler aufgetreten!\n");
			} // end of try

			printf("\n\nNoch eine Person einlesen? (j/n)");
			fflush(stdin);
			scanf("%c", &cSign);

			bGoOn		= (cSign == 'j' || cSign == 'J');
		} // end of while
	} catch (...) {
		printf("Es ist ein Fehler aufgetreten!\n");
	} // end of try
} // end of if

oOutFileStream.close();

std::ifstream	oInFileStream(pcstrFileName, std::ios_base::binary);

// Wenn die Dateien geöffnet werden konnten
if (oInFileStream.is_open()) {
	try {
		printf("== Ausgabe ========================\n\n");

		// Solange es noch etwas zum auslesen gibt
		while (!oInFileStream.eof()) {
			SPerson sPerson;

			try {
				oInFileStream.read((char*)&sPerson, sizeof(SPerson));

				// Nur wenn noch was eingelesen werden konnte
				if (!oInFileStream.eof()) {
					printf("Vorname:  %s\n", sPerson.astrVorname);
					printf("Nachname: %s\n", sPerson.astrNachname);
					printf("Alter:    %i\n", sPerson.iAlter);
					printf("Gewicht:  %g\n\n", sPerson.fGewicht);
				} // end of if
			} catch (...) {
				printf("Beim Einlesen ist ein Fehler aufgetreten!\n");
			} // end of try
		} // end of while
	} catch (...) {
		printf("Es ist ein Fehler aufgetreten!\n");
	} // end of try
} // end of if
					

Die Ausgabe sieht wieder genauso aus, wie vorhin, aber vom Quelltext her hat sich einiges geändert. Es geht schon in Zeile 4 los. Genauso wie bei den Textdateien, habe ich ein Streamobjekt erzeugt, jedoch mit einem zusätzlichen Parameter, um zu signalisieren, dass die zu bearbeitende Datei eine Binärdatei ist.

In Zeile 22 wird jetzt das schreiben in die Datei angestoßen. Allerdings benutze ich dieses mal nicht den Serialisierungsoperator, da jener nur mit reinem Text funktioniert bzw. wenn man mit Textdateien arbeitet. Sehr merkwürdig ist hier, dass ich die zu schreibende Variable in einen char Pointer caste. Dies ist notwendig und hat folgenden Hintergrund. Der Stream schreibt und ließt immer Byteweise. Jeder Datentyp ist ja ohne Rest in n Bytes teilbar (auch für ein bool wird intern ein Byte Speicher benötigt). Diese eingelesenen Bytes, werden also in den RAM bzw. die Datei geschrieben, ohne wirkliche Chars zu sein (ein Char ist nun mal ein elementarer Datentyp, der genau ein Byte groß ist). Da die Methode "write" ein Pointer erwartet, muss ich nicht die Struktur selber, sondern seine Adresse übergeben, was das "&" erklärt.

In Zeile 37 schließe ich jetzt händisch die Datei, da ich sie sonst in Zeile 38 nicht wieder mit dem anderen Streamobjekt öffnen kann (auch hier wieder im Binärmodus).

In Zeile 51 wird das Lesen aus der Datei veranlasst und wie eben schon+ angedeutet, ist auch hier wieder ein Casten auf einen Char-Pointer notwendig und man kann ebenfalls nicht die Serialisierungsoperatoren verwenden.

Wenn man dieses Beispiel adaptiert, kann man auch Textdateien händisch kopieren und bekommt dann auch alle Sonderzeichen, wie Leerzeichen und Zeilenumbrüche, mit. Als Variable muss man lediglich ein einzelnes Char benutzen (niemals eine Zeichenkette, da sonst am Ende der Datei, unter Umständen, etwas fehlen könnte).

Zum Seitenanfang
Zum Inhaltsverzeichnis

© Copyright by Thomas Weiß, 2009 - 2012