C# - Wie ein struct als Datei speichern?

zokker13

Moderator

Mitglied seit
12 Okt 2008
Beiträge
6.719
Punkte
235
Moin,

in der Schule haben wir zur Zeit tolle Themen mit structs, Pointern und File- Operationen und speichern demnach ganze Strukturen.
Das ist alles in C++ gehalten und ist recht unkompliziert.

Hier mal code in C++ (dann muss ich weniger schreiben):
Code:
#include <iostream>
#include <string.h>

using namespace std;


struct TWe
{
	char Name[30];
	char Vorname[30];
	char Ort[30];
};

int main ()
{
	TWe *we = new TWe;

	char _nm[30];
	cout << "Name: ";
	cin >> _nm;
	strcpy(we->Name, _nm);

	char _vrnm[30];
	cout << "Vorname: ";
	cin >> _vrnm;
	strcpy(we->Vorname, _vrnm);

	char _rt[30];
	cout << "Ort: ";
	cin >> _rt;
	strcpy(we->Ort, _rt);


	FILE *f = fopen("C:/temp/test.dat", "w");
	fwrite(we, sizeof(we), 1, f);
	fclose(f);


	return 0;
}

So, nun zur Frage:
Gibt es eine ähnliche Funktion/ Methode wie man das in C# realisieren kann?
Laut Internet muss ich das aufwendig casten oder den Inhalt der Struktur einzeln einpflegen.


Danke im Voraus! : )
 
Mitglied seit
5 Jul 2002
Beiträge
4.802
Punkte
0
Hmpf, Osbes weiss' es vermutlich genauer..
[kein gewaehr]
#include <iostream> wird using System;

'std::cout<< i;' wird ersetzt durch 'Console.Write({i},i);'

'int main()' wird 'static void Main()' [da returned nix ausser ner 0 bei erfolgreicher temination, also warum nich gleich void?]

struct TWe
{
char Name[30]; --> public char[30] Name;
char Vorname[30]; --> etc pp
char Ort[30];
};
@output in eine datei:
string simpleString123 = "hello World";
File.WriteAllBytes("output.dat", StringToByteArray(simpleString123));

[/kein gewaehr]

ansonsten einfach cpp in cs umbennenen, kompilieren, den kompilerfehlern folgen und am ende sicherstellen dass das program sich noch so verhaelt wie der cpp code..
 
Mitglied seit
19 Nov 2011
Beiträge
145
Punkte
0
Kommt ganz darauf an, wie ihr das machen sollt oder welche Hilfsmittel erlaubt sind. Wie sieht den die Struktur in C# aus? Arrays vom Typ char? Oder Strings?

Code:
[Serializable]
struct TWe
{
        public string Name;
        public string Vorname;
        public string Ort;
}

TWe we = new TWe;
we.Name = "...";
...

FileStream stream = new FileStream("C:\\temp\\test.dat", FileMode.CreateNew);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, we);
stream.Close();
Dies speichert die Daten aber nicht lesbar in der Datei, und die Datei wird auch größer, als wenn man manuell nur dreimal die Daten eines char[30]-Arrays speichern würde.

Manuell geht auch das Speichern der einzelnen Strings in die Datei (anstelle der beiden Zeilen, die den Formatter benutzen):
Code:
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(we.Name);
writer.Write(we.Vorname);
writer.Write(we.Ort);
 

zokker13

Moderator

Mitglied seit
12 Okt 2008
Beiträge
6.719
Punkte
235
Hmpf, Osbes weiss' es vermutlich genauer..
[kein gewaehr]
#include <iostream> wird using System;

'std::cout<< i;' wird ersetzt durch 'Console.Write({i},i);'

'int main()' wird 'static void Main()' [da returned nix ausser ner 0 bei erfolgreicher temination, also warum nich gleich void?]

struct TWe
{
char Name[30]; --> public char[30] Name;
char Vorname[30]; --> etc pp
char Ort[30];
};
@output in eine datei:
string simpleString123 = "hello World";
File.WriteAllBytes("output.dat", StringToByteArray(simpleString123));

[/kein gewaehr]

ansonsten einfach cpp in cs umbennenen, kompilieren, den kompilerfehlern folgen und am ende sicherstellen dass das program sich noch so verhaelt wie der cpp code..

Danke für die 1 zu 1 Übersetzung.
Hätte ich nicht gebraucht, schaden kanns aber nicht.

Wenn ich die Daten in eine Methode "StringToByteArray" durch jagen würde, müsste ich das dann wahrscheinlich mit jeden Typen machen.
Die Struktur hat aber weit mehr, als dass ich diese manuell einpflegen wolle.
(Die Struktur dient als Speicher- Struktur)




Kommt ganz darauf an, wie ihr das machen sollt oder welche Hilfsmittel erlaubt sind. Wie sieht den die Struktur in C# aus? Arrays vom Typ char? Oder Strings?
Es gibt keine Anforderung. Der Teil mit der Schule war dem C++- Programm gewidmet. Die C#- Version ist für mich.
Prinzipiell ist es egal ob string oder char[]. Ich bevorzuge natürlich strings.
Das würde aber auch eine Abspeicherung hintereinander unmöglich machen.


Code:
[Serializable]
struct TWe
{
        public string Name;
        public string Vorname;
        public string Ort;
}

TWe we = new TWe;
we.Name = "...";
...

FileStream stream = new FileStream("C:\\temp\\test.dat", FileMode.CreateNew);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, we);
stream.Close();
Dies speichert die Daten aber nicht lesbar in der Datei, und die Datei wird auch größer, als wenn man manuell nur dreimal die Daten eines char[30]-Arrays speichern würde.
Ich habe ein paar Testwerte eingegeben, die ich mit Notepad++ lesen konnte. Ganz unleserlist ist das nicht.
Mein Ziel ist es, dass die Datei völlig wirr und unleserlich für den End-Benutzer wird.


Manuell geht auch das Speichern der einzelnen Strings in die Datei (anstelle der beiden Zeilen, die den Formatter benutzen):
Code:
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(we.Name);
writer.Write(we.Vorname);
writer.Write(we.Ort);
Diese Lösung habe ich schon Online gesehen.
Leider erkennt man die Werte trotzdem. :/


Ich denke, dass ich die Einstellungen einfach in normalen Text abspeichern werde.
Aber danke für euche Hilfe!
 
Mitglied seit
19 Nov 2011
Beiträge
145
Punkte
0
Prinzipiell ist es egal ob string oder char[]. Ich bevorzuge natürlich strings.
Das würde aber auch eine Abspeicherung hintereinander unmöglich machen.
Nö, nicht unbedingt. Du kannst immer ein char-Array speichern, du musst nur selbst dafür sorgen, dass du es auch wieder richtig einliest, da solche Informationen verloren gehen. Sauberer ist aber der String, denn mit den BinaryWriter/BinaryReader-Klassen wird diese Verwaltung übernommen. Es wird immer die Länge mitgespeichert und beim Auslesen geht alles automatisch. Am Besten ist jedoch die Methode mit der Serialisierung, weil du dir dort über die Struktur der Daten keine Gedanken machen musst (es wird aber kompliziert, wenn sich die Struktur später ändert).

Ich habe ein paar Testwerte eingegeben, die ich mit Notepad++ lesen konnte. Ganz unleserlist ist das nicht.
Mein Ziel ist es, dass die Datei völlig wirr und unleserlich für den End-Benutzer wird.
Dass es unleserlich sein soll habe ich wohl überlesen ;)
Du kannst jederzeit anstelle des FileStreams einen MemoryStream verwenden und nach dem Füllen und vor dem Schreiben in die Zieldatei die Bytes verändern (negieren oder etwas addieren). Vor dem Lesen musst du jedoch den Dateiinhalt erst wieder in ein MemoryStream einlesen und dies rückgängig machen.
 

zokker13

Moderator

Mitglied seit
12 Okt 2008
Beiträge
6.719
Punkte
235
Das Problem wird ja sein, dass sich die Struktur (durch neue Funktion) zwangsläufig erweitert.
So oder so muss ich die Daten "per Hand" einlesen und ggf. in ein neues Strukt überführen.

Bezüglich des Memorystreams: Da könnte ich mir den Part auch schenken und die gesamte Datei nach dem speichern mit einer einfachen Verschlüsselung verändern.
Ich denke ich werde es so machen!


Danke für deine Hilfe und Anregungen!
 
Oben Unten