StreamReader und Text-Codierung



  • Ich kann von meiner Bank über Home-Banking Kontoauszüge in Form einer CSV-Datei speichern und diese weiterverarbeiten.
    Dazu benutze ich zunächst folgende einfache Einleseroutine

                using (TextReader reader = new StreamReader("vonBank.csv", Encoding.UTF8))
                {
                    string line; 
                    while ((line = reader.ReadLine()) != null)
                    {
                        listBox1.Items.Add(line);
                    }
                }
    

    Gleich am Anfang der CSV-Datei kommt der erste Umlaut, ein "ä" = 0xE4. Dieses ä wird als sehr komisches Zeichen angezeigt.

    0000: 55 6D 73 E4  74 7A 65 20  54 6F 70 2D  47 69 72 6F :Umsätze Top-Giro:
    0010: 6B 6F 6E 74  6F 20 28 30  30 29 3B 3B  3B 4B 75 6E :konto (00);;;Kun:
    

    Wie muss man es anstellen, damit der Ansi-Code in einen UTF-8 Code während des Lesens (oder danach) konvertiert wird. Die Angabe Encoding.UTF8 bewirkt nichts, ich kann sie auch weglassen.

    Kann man bei der Definition eines Strings, z.B.

    string line; 
    

    angeben, ob das ein UTF-8 String sein soll ?
    Oder beim StreamReader, ob die Eingabedatei UTF8, Ansi, UTF16 o.a. ist.



  • AFAIK ist die Angabe des encodings beim StreamReader dafür da, um anzugeben mit welchen Encoding die eingelesenen Daten interpretiert werden sollen.
    Der StreamReader liest die zeichen und interpretiert sie mit dem angegeben Encoding um sie dann nach Unicode (interne Representation von zeichen bei C#) zu konvertieren.

    Du musst also beim StreamReader das passende ANSI Encoding angeben damit aus 0xE4 = 'ä' in unicode wird (Könnte CP-1252, aka Windows 1252 sein)



  • @firefly , bei Encoding kann man nicht allzuviel angeben. Ich habe es mit Ascii probiert, da wurden die Umlaute ( > 0x7F ) in "?" Fragezeichen gewandelt.
    Jetzt habe ich Encoding.Default angegeben, damit funktioniert es. Die Umlaute sind zu lesen. Das 4. Zeichen "ä" wird im Debugger als 0x00E4 angezeigt, also nicht in UTF8 konvertiert.
    Welchen Zeichencode hat die variable "line" ?

    Ich habe die einzelnen Sätze ausgegeben, In der Ausgabedatei wird "ä" als 0xC3 0xA4 dargestellt, also als ein UTF8-"ä".



  • C# Verwendet intern UTF-16 für Strings. Dass bei der Ausgabe UTF-8 rauskommt liegt wohl daran, dass dort UTF-8 als Encoding angegeben wurde

    Andere Encondings kann man auch bekommen (Es gibt ein paar vordefinierte statische Properties bei der Encoding Klasse)

    z.b. Für CP-1252 geht das wie folgt:

    Encoding wind1252 = Encoding.GetEncoding(1252);
    


  • @firefly
    Bei der Ausgabe ist folgendes codiert:

     StreamWriter writer = File.CreateText("D:\\VC2017\\HK\\TestCs\\TestAusgabe.txt");
    

  • Administrator

    File.CreateText erstellt eine UTF-8 Textdatei:

    https://docs.microsoft.com/en-us/dotnet/api/system.io.file.createtext#System_IO_File_CreateText_System_String_

    Creates or opens a file for writing UTF-8 encoded text.

    Mit Encoding.Default wäre ich sehr vorsichtig. Empfehle dieses nicht zu verwenden. Es kann ganz unterschiedliche Encodings haben je nach Einstellungen auf dem Computer. Verwende lieber Encoding.GetEncoding.



  • @Dravere ,
    Danke für den Hinweis. Jetzt sieht die Anweisung folgendermaßen aus, und das funktioniert auch...

     using (TextReader reader = new StreamReader(DateinameE, System.Text.Encoding.GetEncoding("ISO-8859-1")))
    


  • So wie du den StreamReader instanzierst muss die Quelldatei (vonBank.csv) im UTF-8-Format vorliegen. In C# selbst sind dann alle Strings sowieso UTF16, das ist nicht änderbar und auch keine gute Idee daran herumzuwerken.

    Dein File scheint aber nicht als UTF-8 vorzuliegen, sonst müsste im Hex-Code für ein "ä" "c3 a4" stehen. Finde raus mit welchem Encoding deine Bank das File ablegt (versuch bspw. mal ISO-8859-1) und gib dann dieses Encoding beim StreamReader an.

    MfG SideWinder

    Edit: das kommt davon wenn man Tabs aufmacht und nicht refreshed vor dem Antworten.....


Anmelden zum Antworten