Dateigrösse einer Textdatei herausfinden
-
Hi Zusammen
Ich hab ein Problem. Ich hab ein Tool geschrieben, das von einem Gerät Daten über eine serielle Schnittstelle empfängt. Diese Daten werden danach in ein Textfile geschrieben. Mein Problem ist nun, dass die Datei nach ein Paar Tagen Laufzeit ca 1.5 GB gross wird und sich somit nicht mehr vom standard Windows Editor öffnen lässt.Das einfachste wäre wohl einen anderen Editor zu verwenden, kommt jedoch nicht in Frage.
Ich habe nun herausgefunden, dass mich
seekg(0, ios::end);und
tellg();ans Ziel bringen.
Nur verstehe ich nicht, wie man diese Funktionen verwendet.
Bisher habe ich diesen Code:
// load a file into memory #include "stdafx.h" #include <iostream> #include <fstream> #include <ctime> using namespace std; long GetDateigroesse(fstream); int main() { //... fstream logStream("test.txt",ios::in|ios::out|ios::binary); long dateigroesse; logStream.open("test.txt"); //... dateigroesse = GetDateigroesse(logStream); cout << dateigroesse; return 0; } long GetDateigroesse(fstream stream) { stream.seekg(0, ios::end); return stream.tellg(); stream.clear(); }Jedoch gibt mir die Funktion GetDateigroesse immer -1 zurück, was für mich keinen Sinn ergibt.
Hat jmnd ne Ideee an was es liegen könnte?
-
Dein stream Objekt ist ungültig, da du call-by-value benutzt und sich stream Objekte nicht kopieren lassen. Übergib stream per Referenz und schau, was dann passiert.
-
Du musst den Stream als Referenz übergeben. Außerdem öffnest du die datei 2 mal! Einmal mit leserechten einmal ohne... Darum immer -1 der Fehlerwert.
-
Danke, habt mich auf die lösung gebracht:
Habs noch etwas einfacher geschrieben
#include "stdafx.h"
#include <iostream>
#include <fstream>
using namespace std;int main() { ofstream filewrite("test.txt", ios::app); /*for(int i = 0; i < 100000000000; i++) { filewrite << "i"; } */ ifstream file( "test.txt"); file.seekg( 0, ios::end ); // analog... size_t length = file.tellg(); file.seekg( 0, ios::beg ); cout << length; return 0; }
-
Ich dachte du wolltest es in einer Funktion lösen oO

-
Warum merkst du dir nicht einfach wie viele Daten du schon geschrieben hast und schreibst nach einer bestimmten Größe in eine neue Datei?
So wie sich dein Ansatz jetzt anhört schreibst du die Daten in eine große Datei und kopierst sie dann später in kleinere Dateien. Das ist aus verschiedenen Gründen eher suboptimal. Operationen auf solch große Dateien sind sehr langsam. Du benötigst unnötig viel Speicher, weil die Daten Prinzip bedingt doppelt vorhanden sind. Wenn auch nur kurzzeitig. Und du bekommst Probleme, wenn du die maximale Dateigröße deines Dateisystems erreichst. Auch willst du alte Versionen sicher löschen, weil sie unnötig geworden sind oder der Platz knapp wird. Bei einer großen Datei müsstest du jetzt wieder tricky Daten umher kopieren, bei kleinen Dateien löschst du einfach die ältesten.
-
Nick Unbekannt schrieb:
Warum merkst du dir nicht einfach wie viele Daten du schon geschrieben hast und schreibst nach einer bestimmten Größe in eine neue Datei?
So wie sich dein Ansatz jetzt anhört schreibst du die Daten in eine große Datei und kopierst sie dann später in kleinere Dateien. Das ist aus verschiedenen Gründen eher suboptimal. Operationen auf solch große Dateien sind sehr langsam. Du benötigst unnötig viel Speicher, weil die Daten Prinzip bedingt doppelt vorhanden sind. Wenn auch nur kurzzeitig. Und du bekommst Probleme, wenn du die maximale Dateigröße deines Dateisystems erreichst. Auch willst du alte Versionen sicher löschen, weil sie unnötig geworden sind oder der Platz knapp wird. Bei einer großen Datei müsstest du jetzt wieder tricky Daten umher kopieren, bei kleinen Dateien löschst du einfach die ältesten.Nein. Bisher schrieb ich eine grosse Datei, die ab einer gewissen Grösse nicht mehr geöffnet werden konnte.
Das mit dem ab einer bestimmten Grösse in eine neue Datei schreiben, ist genau das was ich vorhatte. Leider hänge ich bei dieser Aufgabe.
Hier ist der Code, der dies theoretisch erledigen sollte. Wenn die gewünschte Grösse erreicht wurde sollte es mir die FileNumber erhöhen und ein neues File mit neuem FileNamen erstellen. Jedoch estellt es mir 1000ende leere Files mit Total komischen Dateinamen wie z.B.
ng too long.txt
P¿@.txt
ring too long.txt
badbit set.txt
%p.txtMacht das in euren Augen Sinn? Bin total am Ende meiner Ideen.
// load a file into memory #include <iostream> #include <fstream> #include <ctime> #include <string> using namespace std; int main() { unsigned long maxFileSize = 5; int fileNumber = 1; string fileName; char *fileNamePart1 = "log_"; string fileNamePart2 = ".txt"; ofstream filewrite("test.txt", ios::app); for(int i = 0; i < 500000000; i++) { filewrite << "i"; ifstream file( "test.txt"); file.seekg( 0, ios::end ); // analog... size_t length = file.tellg(); file.seekg( 0, ios::beg ); if (length > maxFileSize) { fileNumber++; fileName = fileNamePart1 + fileNumber + fileNamePart2; ofstream filewrite(fileName.c_str(), ios::app); ifstream file( fileName.c_str()); file.seekg( 0, ios::end ); // analog... size_t length = file.tellg(); file.seekg( 0, ios::beg ); cout << length << endl; } } return 0; }
-
HighLigerBiMBam schrieb:
Ich dachte du wolltest es in einer Funktion lösen oO

Ist nur Beispielcode. Wenn ich es in meinem Programm einbaue werde ich schon eine Funktion daraus machen.
-
Gehen wir das mal logisch durch: Du hast eine Schleife mit 5000000 Aufrufen. Wenn die Datei text.txt zu groß ist, dann soll eine neue Datei erstellt werden. So weit so gut. jetzt passiert aber folgendes: Die Datei ist bei i = 4000000 voll bsp. und dann wird dies nochmal 1000000 mal durchgeführt und geschaut, ob text.txt voll ist, was es ja schon bei 4000000 war und auch bei den nächsten 1000000 schritten sein wird. Somit bekommst du deine 1000000 Dateien

-
Wie geschrieben, zähle die Bytes selber mit. Das ist auch schneller. Und wenn eine bestimmte Zahl an Bytes erreicht ist, schließt du die Datei, bastelst dir einen neuen Namen zusammen (dazu kann man sich eine fortlaufende Nummer merken), und öffnest die neue Datei.
-
HighLigerBiMBam schrieb:
Gehen wir das mal logisch durch: Du hast eine Schleife mit 5000000 Aufrufen. Wenn die Datei text.txt zu groß ist, dann soll eine neue Datei erstellt werden. So weit so gut. jetzt passiert aber folgendes: Die Datei ist bei i = 4000000 voll bsp. und dann wird dies nochmal 1000000 mal durchgeführt und geschaut, ob text.txt voll ist, was es ja schon bei 4000000 war und auch bei den nächsten 1000000 schritten sein wird. Somit bekommst du deine 1000000 Dateien

Achsoo.. so weit habe ich nicht überlegt;)
Nick Unbekannt schrieb:
Wie geschrieben, zähle die Bytes selber mit. Das ist auch schneller. Und wenn eine bestimmte Zahl an Bytes erreicht ist, schließt du die Datei, bastelst dir einen neuen Namen zusammen (dazu kann man sich eine fortlaufende Nummer merken), und öffnest die neue Datei.
Gibts einen Datentypen, der bytes bis zu 2'000'000'000 zählen kann?
-
Es gibt größre Datentypen.
-
Rechne es doch aus:
232-1 = 4.295 * 109
Falls dir das nicht reicht, unterstützt dein Compiler sicher einen 64 Bit breiten unsigned Integer:
264-1 = 1.849 * 1019
-
Nick Unbekannt schrieb:
Wie geschrieben, zähle die Bytes selber mit. Das ist auch schneller. Und wenn eine bestimmte Zahl an Bytes erreicht ist, schließt du die Datei, bastelst dir einen neuen Namen zusammen (dazu kann man sich eine fortlaufende Nummer merken), und öffnest die neue Datei.
Du hast recht die Version mit tellg() und seekg() kann ich vegessen, ist viel zu langsam.
Ich habs jetzt versucht mit den bytes selber zählen. Jedoch wenn es mir das neue File erstellt, schreibt es weiterhin ins alte. Muss ich den alten Stream i-wie löschen?
Habs so bis jetzt.
// load a file into memory #include <iostream> #include <fstream> #include <ctime> #include <string> using namespace std; #include <sstream> int main() { unsigned long fileSize = 457; int fileNumber = 1; string strFileNumber; std::stringstream out; out << fileNumber; strFileNumber = out.str(); string rawLogFileName = "raw_" + strFileNumber + ".txt"; //Create LogFile ofstream oStreamRawLog; oStreamRawLog.open(rawLogFileName.c_str(), ios::app); //Create Raw Log File Header oStreamRawLog << "String Comment: " << "sdsdsds" <<"\n" << endl; oStreamRawLog << "Parameters: " << endl; oStreamRawLog << "ComPort: " << "comPort" << "\n" << "Baud Rate: " << "baudRate " << "\n" << "Min Delay: " << "minDelay " << "\n" << "Max Delay: " << "maxDelay " << "\n" << "Expected BitError: " << "expBitError" << "\n" << "----------------------------------------" << endl; oStreamRawLog << "Version: " << " version " << endl; oStreamRawLog << "Operating PC: " << " computerName " << endl; oStreamRawLog << "Operating User: " << " userName " << endl; oStreamRawLog << "Start Time: " << " dateTime.DateTime()" << endl; //First Line oStreamRawLog << "\n\nDate:\t\t\t" << "Time: [ms]\t\t\t" << "Data Received:\t\t\t" <<"BitErrors:\t\t"<< "Delay:" <<endl; while (true) { if(fileSize >= 1000000) { delete oStreamRawLog; fileNumber ++; std::stringstream out; out << fileNumber; strFileNumber = out.str(); string rawLogFileName = "raw_" + strFileNumber + ".txt"; //Create LogFile ofstream oStreamRawLog; oStreamRawLog.open(rawLogFileName.c_str(), ios::app); //Create Raw Log File Header oStreamRawLog << "String Comment: " << "sdsdsds" <<"\n" << endl; oStreamRawLog << "Parameters: " << endl; oStreamRawLog << "ComPort: " << "comPort" << "\n" << "Baud Rate: " << "baudRate " << "\n" << "Min Delay: " << "minDelay " << "\n" << "Max Delay: " << "maxDelay " << "\n" << "Expected BitError: " << "expBitError" << "\n" << "----------------------------------------" << endl; oStreamRawLog << "Version: " << " version " << endl; oStreamRawLog << "Operating PC: " << " computerName " << endl; oStreamRawLog << "Operating User: " << " userName " << endl; oStreamRawLog << "Start Time: " << " dateTime.DateTime()" << endl; //First Line oStreamRawLog << "\n\nDate:\t\t\t" << "Time: [ms]\t\t\t" << "Data Received:\t\t\t" <<"BitErrors:\t\t"<< "Delay:" <<endl; fileSize = 457; } oStreamRawLog << "XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX\n"; fileSize += 66; cout << fileSize; } return 0; }
-
Mich wundert es das das überhaupt compiliert.
Was soll das denn bewirkendelete oStreamRawLog;?
Lass das weg.
Du schreibst weiter in deine alte Datei, weil du eine neue oStreamRawLog Variable innerhalb des Scopes vin if(..) aufmachst. Diese variable ist auch nur dort gültig. Nach verlassen deises Blocks schreibst du wieder in die alte Variable.
Also, statt des deletes ein oStreamRawLog.close() um die alte datei zu schliessen.
Hier:ofstream oStreamRawLog; // neue Streaminstanz oStreamRawLog.open(rawLogFileName.c_str(), ios::app); // wozu das ios.app?lass einfach die Erzeugung einer neuen Instanz weg.
-
Braunstein schrieb:
Mich wundert es das das überhaupt compiliert.
Was soll das denn bewirkendelete oStreamRawLog;?
Lass das weg.
Du schreibst weiter in deine alte Datei, weil du eine neue oStreamRawLog Variable innerhalb des Scopes vin if(..) aufmachst. Diese variable ist auch nur dort gültig. Nach verlassen deises Blocks schreibst du wieder in die alte Variable.
Also, statt des deletes ein oStreamRawLog.close() um die alte datei zu schliessen.
Hier:ofstream oStreamRawLog; // neue Streaminstanz oStreamRawLog.open(rawLogFileName.c_str(), ios::app); // wozu das ios.app?lass einfach die Erzeugung einer neuen Instanz weg.
Danke. Jetzt funktionierts.