binary datei wieder einlesen und ausgeben wie?



  • Hi

    Ich bin blutiger Anfänger und spiele nur gerade etwas mit binary Dateien herum.

    Mein Ziel ist Daten bestehend aus int's von 0 bis 60000 als Binary Datei
    (edit: platzsparend)zu speichern und dieses Binary wieder einzulesen in die int's alle per cout
    wieder auszugeben.

    Ich bin davon ausgegangen das ich je zwei Byte für eine Zahl benötige wenn alle Zahlen zwischen 0 und 256² (65536) liegen.

    Ich habe ein vector mit Zahlen von 0 bis 59999 gefüllt und diesen dann in die Datei geschrieben mit einer "streamsize" von 2 byte. Ich hoffe bis hierhin ist alles richtig. Zumindest sieht das Binary im Hex-Editor korrekt aus:

    00 00 01 00 02 00 03 00 04 00 05 00 06 00 07 00 08 00 09 00 0A 00 0B 00 ...
    

    Das ist das Programm:

    #include <fstream>
    #include <iostream>
    #include <vector>
    using namespace std;
    
    vector<int> data;
    vector<int> data_in;
    int main(){
    	
    	// generate numbers to 60000
    	for(int i=0;i<60000;i++){
    		data.push_back(i);
    	}
    	
    	ofstream file_b("binary.bin", ios::binary | ios::trunc);
    	ifstream file_i("binary.bin", ios::binary);
    	
    	// write to binary
    	if(!file_b){
    		cout << "file_b error" << endl;
    	}else{
    		for(int i=0;i<data.size();i++){
    			file_b.write(reinterpret_cast<char*>(&data[i]), 2); 	// 
    		}
    		file_b.close();
    	}
    	
    	// read back from binary and print all values
    	if(!file_i){
    		cout << "file_i error" << endl;
    	}else{
    		file_i.seekg(0, ios::end);		// set getpointer to 0
    		int filesize = file_i.tellg();  // get filesize
    		
    		file_i.close();
    	}
    	
    	return 0;
    }
    

    Nun komme ich einfach nicht drauf wie ich die Binary Daten wieder 2 byte-weise einlesen kann? Ich habe jetzt schon mal versucht die Dateigröße herauszufinden (120000 bytes) und meine Idee wäre nun irgendwie bis zu dieser Zahl durchzu-interieren. Ich komme aber einfach nicht drauf wie das gehen soll.

    Kann mich jemand erleuchten? 🙂



  • Du liest die Daten analog mit read wieder ein.

    Aber noch ein paar Hinweise bzw. Verbesserungsvorschläge:

    • öffne die Datei zum Lesen erst nachdem du diese auch geschrieben hast (also die Zeile ifstream file_i(...) weiter nach unten verlagern)
    • ein int hat auf den meisten Systemen 4 Byte (d.h. du könntest einfach sizeof(int)anstatt 2 benutzen) - alternativ unsigned short als Datentyp
    • mittels while (file_i) (bzw. if (file_i)) kannst du abfragen, ob noch weitere Daten zum Lesen zur Verfügung stehen - genauergesagt, ob der Stream noch in einem gültigen Zustand ist (anstatt die Größe der Datei abzufragen).


  • This post is deleted!


  • @Th69 sagte in binary datei wieder einlesen und ausgeben wie?:

    du könntest einfach sizeof(int)anstatt 2 benutzen

    Das würde aber die Binary Datei nur unnötig vergrößern oder?
    Die Datei wäre dann doppelt so groß (240000 bytes statt 120000)...



  • @pauledd sagte in binary datei wieder einlesen und ausgeben wie?:

    @Th69 sagte in binary datei wieder einlesen und ausgeben wie?:

    du könntest einfach sizeof(int)anstatt 2 benutzen

    Das würde aber die Binary Datei nur unnötig vergrößern oder?
    Die Datei wäre dann doppelt so groß (240000 bytes statt 120000)...

    Mit sizeof ist es aber richtig.

    Das mit 2 funktioniert hier nur, weil der TO ein Little-Endian-System hat.



  • @DirkB sagte in binary datei wieder einlesen und ausgeben wie?:

    Mit sizeof ist es aber richtig.
    Das mit 2 funktioniert hier nur, weil der TO ein Little-Endian-System hat.

    Haben nicht annähernd alle Desktops (x64) Little-Endian?

    Nur um das evtl. nochmal deutlicher zu machen warum ich zwei Byte zum schreiben der Binary Datei verwendet habe.
    Es geht wie gesagt darum Platz zu sparen und Daten mit int Werten von 0-60000 in eine Datei zu schreiben. Würde ich das als normale Textdatei ausgeben würde das ja schnell sehr groß werden. Deshalb habe ich versucht die an sich 4 Byte int werte in ein WORD mit 2 Byte zu packen. Gesehen habe ich das hier:

    https://www.thethingsnetwork.org/docs/devices/bytes.html#3-use-words

    Da das ganze aber für den Arduino geschrieben ist hatte ich nur den Versuch gestartet das mal auf dem PC zu schreiben...



  • @pauledd Dann wandele vorher in short um bzw. in unsigned short

    Je nach CPU ist auf dem Arduino ein int auch nur 2 Byte groß.



  • Ich glaube ich habe es geschafft. Ich habe als Behälter für das WORD
    ein 2-Byte u_char array erstellt und dann beide Werte des Arrays wieder vereint mit Bitshift, oder wie man das nennt 😁

    Hier noch der ganze Code:

    #include <fstream>
    #include <iostream>
    #include <vector>
    using namespace std;
    
    vector<int> data;
    int out(0);
    u_char word[2];
    
    int main(){
    	
    	// generate numbers to 60000
    	for(int i=0;i<60000;i++){
    		data.push_back(i);
    	}
    	
    	// write to binary
    	ofstream file_b("binary.bin", ios::binary | ios::trunc);
    	if(!file_b){
    		cout << "file_b error" << endl;
    	}else{
    		for(int i=0;i<data.size();i++){
    			file_b.write(reinterpret_cast<char*>(&data[i]), sizeof(word)); 	// 
    		}
    		file_b.close();
    	}
    	
    	// read back from binary and print all values
    	ifstream file_i("binary.bin", ios::binary);
    	if(!file_i){
    		cout << "file_i error" << endl;
    	}else{
    		while(file_i){
    			file_i.read(reinterpret_cast<char*>(&word),sizeof(word));
    			out = (word[1]<<8)|(word[0]);
    			cout << out << endl;
    		}
    		file_i.close();
    	}
    	
    	return 0;
    }
    

    Die Ausgabe sieht dann wie gewünscht so aus:

    0
    1
    2
    ...
    59999
    

Log in to reply