größere Dateien(10 bis 200 MB) lesen
-
Ich sehe keinen Code, der eine Datei einliest. Wenn du wissen willst, warum das so lange dauert, solltest du den Einleseteil vielleicht auch posten.

Prinzipiell sollte dein Buffer zum Einlesen nicht zu klein sein, sonst ist der Overhead für jeden einzelnen Einlesevorgang zu groß und bremst das unnötig.
-
lilian schrieb:
es funktioniert einwandfrei. Aber mein Problem ist: wenn ich größere Dateien ab 10Mb dann dauert es halt sehr lange!
gibt´s Alternativen bzw. Funktionen die den Prozess beschleunigen oder spezielle func die die datei im Hintergrund liest ohne sie zu laden ?
vielen DankWas genau dauert lange. In deinem Beispiel zeigst du uns ja nicht wie du das File liest, nur wie du es öffnest und dabei kann man wirklich nicht viel optimieren.
Kurt
-
hallo
Danke für die zahlreichen Antworten.
also beim Lesen habe die Funktion "getline" benutzt. also zeilenenweise lesen
hier ist der ganze Code:int readFile() { //-------------- Existenztest der Datei -------------------------- char szfile[50]; ifstream file; do { file.clear(); //clear status flags des Inputstreams "dat" cout<<"Dateiname inklusive Pfad eingeben: "; cin>>szfile; file.open(szfile,ios::in); // "dat" wird geöffnet zum Lesen if(file.fail()) // Fehlertest durchführen cout<<"Datei existiert nicht!"<<endl; cout<<"\ndatei is open\n"; }while(file.fail()); //------------------------------------------------------------------- do { string strline,strl1,strl2,str3; int nrow; do { if(bheader==false) { // string strline,strl; string str2= "time_record for"; string str="Rec "; // int i=0; getline(file,strline); if(strline!="") { for(int k=0;k<15;++k) { strl1.resize(k+1); strl1[k]=strline[k]; } if (str2 == strl1) // wenn strl1 == "time_record for" { for(int m=16; m<strline.size(); ++m) { str3.resize(m-15); str3[m-16]=strline[m]; } v_header.push_back(str3); } for(k=0;k<4;++k) { strl2.resize(k+1); strl2[k]=strline[k]; } if (str == strl2) // wenn strl == Rec { getline(file,strline); for (nrow=0;nrow<6; ++nrow) // nur die zweite und die vierte Zeile lesen { getline(file,strline); if(nrow==1) { string a, b, c, d, x, y; std::stringstream(strline)>>a>>b>>c>>d>>x; // v_header.resize(++i); v_header.push_back(x); } if(nrow==3) { string a, b, c, d, x, y; std::stringstream(strline)>>a>>b>>c>>d>>x>>y; // v_header.resize(++i); v_header.push_back(y); bheader=true; } } } } } }while(nrow!=6); if (nrow==6) { int index=0; string s; do { getline(file,strline); for(int k=0;k<15;++k) { s.resize(k+1); s[k]=strline[k]; } if (s=="time_record for") { // printData(); string a, b, c; std::stringstream(strline)>>a>>b>>c; v_header.push_back(c); nrow=0; bheader=false; chi++; continue; } string a,b,c,d,e,f; std::stringstream(strline)>>a>>b>>c>>d>>e>>f; if (a!="" && b!=""&& c!=""&& d!=""&& e!=""&& f!="") { mat_data.resize(chi+1); mat_data[chi].resize(index+6); mat_data[chi][index] = a; mat_data[chi][index+1] = b; mat_data[chi][index+2] = c; mat_data[chi][index+3] = d; mat_data[chi][index+4] = e; mat_data[chi][index+5] = f; index=index+6; } }while(s!="time_record for" && !file.eof()); } }while(!file.eof()); file.close(); return 0; }Danke
-
for(int k=0;k<15;++k) { strl1.resize(k+1); strl1[k]=strline[k]; }Das machst du am besten durch Zuweisung eines Substrings(siehe Link). Jede Anwendung des []-Operators bei Strings ist ja schließlich ein Funktionsaufruf und jedes Resizen auch.
string str2= "time_record for"; string str="Rec ";Die beiden könntest du als const strings außerhalb deiner Einleseschleife definieren, sonst werden sie bei jedem Schleifendurchlauf erneut erzeugt.
string a, b, c, d, x, y; std::stringstream(strline)>>a>>b>>c>>d>>x; v_header.push_back(x);Da du die Strings a,b,c,d,y sowieso nicht benutzt, brauchst du sie auch nicht zu erzeugen. Ich weiß zwar nicht, ob es eine formatierte Ignore-Variante für Streams gibt (mit der Funktion ignore könntest du im Stream zeichenweise ignorieren, wenn die Anzahl immer gleich ist), aber so funktioniert es auch, da von links nach rechts ausgewertet wird:
string x; std::stringstream str(strline) str>>x>>x>>x>>x>>x; v_header.push_back(x);if (a!="" && b!=""&& c!=""&& d!=""&& e!=""&& f!="")Die String-Funktion empty wäre in dem Fall wohl besser geeignet. Es wird zwar bei deinem Vergleich nicht gleich ein String-Objekt ("") erstellt, eleganter ist empty aber doch.
Vielleicht lässt sich da ja noch was optimieren, wenn du uns den Aufbau deiner Dateien verrätst.
http://www.cppreference.com/cppstring/empty.html
http://www.cppreference.com/cppstring/substr.html
-
lilian dein code ist total scheisse. programmier das nochmal neu bitte.
-
Danke
@ masterofx32
ich habe gemacht was du mir verbessert hast aber trotzdem der Leseprozess ist immer noch langsam.
@ net
was ist mit memory mapped files? könnte das Problem damit lösen? ich habe gegoogelt aber nichts gescheites! bitte hilft mir?
vielen Dank
-
Wie sehen denn deine Eingabedateien aus und wie genau willst du sie verarbeiten?
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dngenlib/html/msdn_manamemo.asp
-
mit memory mapping von files kann man einen ausschnitt einer grossen datei in den (virtuellen) speicher abbilden und die datei dann mit ganz normalen speicherzugriffen bearbeiten. guckst du: http://www.catch22.net/tuts/bigmem01.asp
-
vielen Dank für die schnellen Antworten
damit ihr einen Überblick folgendes sehen die einzulesende Dateien (sind zw. 10 und 200MB) aus:-1
NONE
LMS CADA-X TEST APPLICATION
26-Apr-05 14:39:31
-1
-1
164
1 Metric SI
1.00000000000000000D+00 1.00000000000000000D+00 1.00000000000000000D+00
0.00000000000000000D+00
-1
-1
58
time_record for comp:1:+X response / invalid
26-Apr-05 14:38:53
Rec 4720 of test "100-abc"
NONE
1 0 4720 0 comp 1 1 NONE 0 0
2 43008 1 0.00000e+00 2.44141e-04 0.00000e+00
17 0 0 0 NONE s
12 0 0 0 NONE g
0 0 0 0 NONE NONE
0 0 0 0 NONE NONE
-6.16959e-02 1.49747e-02 4.19293e-02 -1.31778e-02 -5.81020e-02 -3.29444e-02
2.99495e-03 1.85687e-02 5.39090e-03 3.59394e-02 -3.53404e-02 -4.13303e-02
-3.17464e-02 2.33606e-02 4.19293e-02 -8.68535e-02 -4.73202e-02 -3.11474e-02
0.00000e+00 9.58383e-03 -1.07818e-02 2.99495e-02 -6.58888e-02 -2.57565e-02
-2.45586e-02 -5.98989e-04 4.79191e-03 -7.66706e-02 -5.63050e-02 -2.69545e-02
-1.25788e-02 -2.93505e-02 -5.63050e-02 -3.53404e-02 -8.38585e-03 -4.19293e-03
-1.25788e-02 -6.76858e-02 -4.01323e-02 -1.85687e-02 4.19293e-03 -1.19798e-03
-4.91171e-02 -5.63050e-02 -2.15636e-02 6.58888e-03 2.33606e-02 -1.55737e-02-1
-1
58
time_record for comp:2:+X response / invalid
26-Apr-05 14:38:53
Rec 4729 of test "100-ujb"
NONE
.........
.............usw.alles was unterschrichen(ich habe die Unterschriche extra für euch hinzugefügt) wird in vektoren gespeichert und in einer extra-Datei geschrieben.
Danke
-
ich habe beim googeln das Beispiel für file mapping gefunden
//open a file, and set the first 99 characters as //uppercase using file mapping void fileExample2(){ char* dataPointer; DWORD maxLen; HANDLE hFile=CreateFile( "hithere.txt",//name of the file GENERIC_READ | GENERIC_WRITE,//desired access FILE_SHARE_READ,//share mode NULL,//security attributes OPEN_ALWAYS,//creation disposition FILE_ATTRIBUTE_NORMAL,//flags and attr NULL);//template file //that's to avoid Windows killing the program maxLen=GetFileSize(hFile,NULL); maxLen=(maxLen>99)?99:maxLen; HANDLE hFM=CreateFileMapping( hFile,//handle NULL,//security PAGE_READWRITE,//flProtect 0,0,//max size NULL);//name dataPointer=(char*)MapViewOfFile( hFM,FILE_MAP_ALL_ACCESS,0,0,0); CharUpperBuff(dataPointer, maxLen//don't pass the limit! ); UnmapViewOfFile(dataPointer); CloseHandle(hFM); CloseHandle(hFile); }wie kann ich das in meinem obigen programm implementieren bzw. mit meinem Code einbinden lassen?
ich brauche dringend eure Hilfe. Danke sehr