Dateigröße wächst stetig an, obwohl der Inhalt immer derselbe ist



  • Abend,

    heute mal eine etwas merkwürdige Thematik: Ich habe zwei Textdateien, foo.txt und bar.txt. Ich schreibe den Inhalt von foo nach bar und vice versa. Was ich nun nicht verstehe, ist, warum sich die Dateigröße hochschaukelt, obwohl der Dateiinhalt immer derselbe ist. Kann mir das jemand erklären?

    #include <iostream>
    #include <fstream>
    #include <iterator>
    #include <string>
    using namespace std;
    
    int main()
    {
    	{
    		wifstream in("foo.txt",std::ios_base::binary);
        	wstring content( istream_iterator<wchar_t,wchar_t>(in>>noskipws), istream_iterator<wchar_t,wchar_t>() );
        	wofstream out("bar.txt");
        	out << content;
    	}
    
    	{
    		wifstream in("bar.txt",std::ios_base::binary);
        	wstring content( istream_iterator<wchar_t,wchar_t>(in>>noskipws), istream_iterator<wchar_t,wchar_t>() );
        	wofstream out("foo.txt");
        	out << content;
    	}
    }
    

    Danke im Voraus.


  • Mod

    Nach jedem Aufruf wird die Datei größer? Ich hätte jetzt nämlich im Verdacht, dass ein Konflikt zwischen der Zeichencodierung der Datei und der Zeichencodierung deiner Streams vorliegt. Aber das sollte nur einmalig etwas ändern, danach sollte es schließlich passen. Vielleicht übersehe ich auch gerade irgendeine verrückte Möglichkeit.

    Jedenfalls kannst du mittels imbue den Streams eine locale andrehen. Ich muss zum Beispiel bei meinem System dein Programm wie folgt abändern, damit es überhaupt eine UTF-8-Datei mit Sonderzeichen korrekt behandelt (meine Systemlokale ("") benutzt UTF-8, die Standardlocale ("C") kommt damit bekannterweise nicht zurecht):

    int main()
    {
      locale mylocale(""); 
        {
            wifstream in("foo.txt",std::ios_base::binary);
            in.imbue(mylocale);
            wstring content( istream_iterator<wchar_t,wchar_t>(in>>noskipws), istream_iterator<wchar_t,wchar_t>() );
            wofstream out("bar.txt");
            out.imbue(mylocale);
            out << content;
        }
    
        {
            wifstream in("bar.txt",std::ios_base::binary);
            in.imbue(mylocale);
            wstring content( istream_iterator<wchar_t,wchar_t>(in>>noskipws), istream_iterator<wchar_t,wchar_t>() );
            wofstream out("foo.txt");
            out.imbue(mylocale);
            out << content;
        }
    }
    

    Da kannst du ja mal die passende Zeichencodierung für deine Datei angeben (falls deine Systemlocale nicht zur Dateilocale passt) und gucken, ob der Fehler immer noch auftritt.



  • SeppJ schrieb:

    Nach jedem Aufruf wird die Datei größer?

    Richtig.

    Ich lege z.B. die Datei foo.txt an und schreibe hinein:

    a
    b
    c
    

    Dann lege ich eine leere bar.txt an. Lasse ich das Programm 1x durchlaufen, hat foo 11Bytes und bar 13Bytes. Nach insgesamt 3 Programmdurchläufen hat foo 19Bytes und bar 21Bytes, etc.

    Ich habe dein Beispiel versucht, sowohl mit "" als auch mit "C" , es hat sich jedoch nichts verändert. Es spielt auch keine Rolle, ob ich mit wchar_t oder char arbeite, der Effekt ist derselbe.


  • Mod

    Ach klar, jetzt wo du die konkreten Zahlen nennst sehe ich es: Du liest binary, schreibst aber nicht binary. In Windows gibt das einen Unterschied von einem Zeichen bei Zeilenumbrüchen. Daher konnte ich den Fehler bei mir auch nicht nachvollziehen.



  • Kleiner Tipp am Rande:

    #include <fstream>
    
    int main() {
      std::wifstream in ("foo.txt", std::ios::binary);
      std::wofstream out("bar.txt", std::ios::binary);
    
      out << in.rdbuf();
    }
    


  • Um genau zu sein ist es so: (ich zitiere einfach mal http://www.c-plusplus.net/forum/p2199823#2199823)

    seldon schrieb:

    Unter Windows werden Textdateien so behandelt, dass Zeilenenden durch "\r\n" dargestellt werden (also zwei Zeichen). Wenn du die Datei im Textmodus öffnest, übernimmt das System die Umwandlung für dich, mit ios::binary kriegst du den Kram halt in Rohfassung und müsstest das \r selbst ignorieren. \r bedeutet "geh wieder zum Anfang der Zeile zurück", und das führt natürlich zu seltsamer Ausgabe, wenn man es einfach drinlässt.



  • SeppJ schrieb:

    Ach klar, jetzt wo du die konkreten Zahlen nennst sehe ich es: Du liest binary, schreibst aber nicht binary.

    Ah nun sehe ich es auch, da hat sich nun bei jedem Schreiben für jeden Zeilenumbruch ein zusätzliches \r reingemogelt. Da ich ja zwei Zeilenumbrüche hatte, erklärt das immer die zwei zusätzlichen Bytes. Danke euch 🙂


Anmelden zum Antworten