Schnelles Einlesen großer Datenmengen: Welches Dateiformat?
-
VerbalKint schrieb:
würdest du das ganze dann mit einer Textdatei machen? Oder ist das Dateiformat eigentlich egal?
Das kommt darauf an

Wenn du mit den Daten auch außerhalb deines Programms etwas anfangen willst (z.B. dir mit dem Wordpad eine Punktesammlung zusammenschreiben), bleibt nur Textformat.
Wenn du die Daten nur im Programm verarbeiten willst, dürfte eine Binärdatei geeigneter sein (ein Punkt besteht aus drei int's oder double's und braucht damit binär genau 3*sizeof(koord_type) Byte (in Textform schwankt die Größe zwischen 6 und ca. 30 Byte je nach Inhalt).PS: Mein Name hat übrigens nur zwei L

-
Hallo.
Ich habe eure Hinweise mal verarbeitet und das ist dabei herausgekommen. Ich würde mich sehr freuen, wenn Ihr mir Verbesserungsvorschläge unterbreitet, wie man es effizienter / schneller machen kann, damit ich was dazu lernen kann

1.Daten in Datei schreiben:
std::fstream filename; filename.open("data.dat",std::ios::out|std::ios::binary); if (filename.is_open()) { for (i=0;i<itsAnz;i++) { itsPkt[i].x = Umkehr(rand()%2)*rand()%grenze; itsPkt[i].y = Umkehr(rand()%2)*rand()%grenze/1000.0; itsPkt[i].z = itsParam[0] + itsParam[1]*itsPkt[i].x + itsParam[2]*itsPkt[i].y; filename << itsPkt[i].x << " " << itsPkt[i].y << " " << itsPkt[i].z << "\n"; // '\n' ist hier wahrscheinlich falsch :confused: } filename.close(); }2.Daten aus Datei lesen:
OpenDialog1->FileName = ""; if (OpenDialog1->Execute()) { filename.open(OpenDialog1->FileName.c_str(),std::ios::in|std::ios::binary); if (filename.is_open()) { nr1 = 0; while (getline(filename,zeile)) { str.str(zeile); nr2 = 0; while (str >> zahl) { if (!nr2) itsPkt[nr1].x = zahl; if (1 == nr2) itsPkt[nr1].y = zahl; if (2 == nr2) itsPkt[nr1].z = zahl; nr2++; } nr1++; } filename.close(); } else Application->MessageBoxA("Datei konnte nicht geöffnet werden!","Fehler",MB_ICONERROR); }Ich danke für Eure Hilfe.
V.K.
-
Erstmal: Was genau steckt hinter den ganzen itsIrgendwas-Variablen?
Zweitens: Die Einlesen-Schleife ist zumindest gefährlich, weil du vorher nicht weißt, wieviele Daten tatsächlich kommen können - das ergibt im Ernstfall einen Speicher-Überlauf (ich hätte mit einem leeren vector<> begonnen und jeweils einen Punkt per push_back() dort reingeschoben).
Drittens: Das Auseinandernehmen der Eingabezeile ist aber reichlich kompliziert - zumal du immer genau drei Werte hast. Da reicht eigentlich:
str.str(zeile); str>>itsPkt[nr1].x>>itsPkt[nr1].y>>itsPkt[nr1].z;//aber achte auf den verfügbaren Platz if(!str) break;PS: Und auch wenn du die Datei im Binärmodus geöffnet hast - op<< und op>> schreiben in Textform. Zum binären Lesen/Schreiben gibt es read() und write().
PPS: Hat dir schonmal jemand gesagt, daß man Variablen auch lokal definieren kann

-
VerbalKint schrieb:
filename << itsPkt[i].x << " " << itsPkt[i].y << " " << itsPkt[i].z << "\n"; // '\n' ist hier wahrscheinlich falsch
Nein, nicht wahrscheinlich.
Totsicher.
MfG
k.d.d.
-
kenner der dummköpfe schrieb:
VerbalKint schrieb:
filename << itsPkt[i].x << " " << itsPkt[i].y << " " << itsPkt[i].z << "\n"; // '\n' ist hier wahrscheinlich falsch
Nein, nicht wahrscheinlich.
Totsicher.Hör nicht auf ihn, er hat zwar Ahnung von Dummköpfen (vermutlich aus praktischer Erfahrung :D), aber nicht von C++.
-
CStoll schrieb:
Hör nicht auf ihn, er hat zwar Ahnung von Dummköpfen (vermutlich aus praktischer Erfahrung :D), aber nicht von C++.

Warum schreibst du denn den Tinnef da mit rein:
filename << itsPkt[i].x << " " << itsPkt[i].y << " " << itsPkt[i].z << "\n";
Ich meine die Leerzeichen und das \n

Nur mal so ne Anmerkung bezüglich Verbesserungsvorschläge, schneller machen und so.
-
Wenn du die Daten in Textform in die Datei schreibst, brauchst du Trennzeichen, um zu wissen, wo eine Zahl aufhört und wo die nächste beginnt (und auch wenn die Datei als ios::binary geöffnet wurde, schreibt op<< trotzdem in Textform).
-
HI.
Ich habe das Ganze jetzt modifiziert. Weis aber nicht, ob jetzt alles richtig ist. Könnte es sich bitte jemand anschauen?
1. Schreiben:
void __fastcall THauptfenster::Zuflligerzeugen1Click(TObject *Sender) { //... std::stringstream data; std::fstream filename; filename.open("data.bin",std::ios::out|std::ios::binary); if (filename.is_open()) { for (i=0;i<itsAnz;i++) { itsPkt[i].x = Umkehr(rand()%2)*rand()%grenze; itsPkt[i].y = Umkehr(rand()%2)*rand()%grenze/1000.0; itsPkt[i].z = itsParam[0] + itsParam[1]*itsPkt[i].x + itsParam[2]*itsPkt[i].y; data << itsPkt[i].x << itsPkt[i].y << itsPkt[i].z; } filename.write(data.str().c_str(),data.str().size()); filename.close(); } }2. Lesen:
void __fastcall THauptfenster::VonDateieinlesen1Click(TObject *Sender) { int i,size; char *data; std::fstream filename; std::string zeile; std::stringstream str; OpenDialog1->FileName = ""; if (OpenDialog1->Execute()) { filename.open(OpenDialog1->FileName.c_str(),std::ios::in|std::ios::binary); if (filename.is_open()) { size = filename.tellg(); data = new char [size]; filename.read (data,size); filename.close(); itsPkt = new Vektor [size/3]; // Kopiere von data nach itsPkt delete[] data; } else Application->MessageBoxA("Datei konnte nicht geöffnet werden!","Fehler",MB_ICONERROR); } }
-
Nein, so wird's nichts - mit dem Stringstream schreibst du immer noch Textdaten.
Bessere Lösung:
vector<point> mydata; //schreiben: fstream datei(name,ios::out|ios::binary); for(i=0;i<mydata.size();++i) { datei.write(reinterpret_cast<const char*>(&mydata[i]),sizeof(point)); } //lesen fstream datei(name,ios::in|ios::binary); point pt; while(datei.read(reinterpret_cast<char*>(&pt),sizeof(point))) mydata.push_back(pt);
-
VIELEN DANK! So funktionierts jetzt endlich!
