Encoding.Default sollte nicht verwendet werden...
Einige Antworten verwenden Encoding.Default
Microsoft erhebt jedoch eine Warnung davor :
Verschiedene Computer können unterschiedliche Kodierungen als Standard verwenden, und die Standardkodierung kann sich auf einem einzelnen Computer ändern. Wenn Sie die Standardkodierung verwenden, um Daten zu kodieren und zu dekodieren, die zwischen Computern gestreamt oder zu unterschiedlichen Zeiten auf demselben Computer abgerufen werden, werden diese Daten möglicherweise falsch übersetzt. Außerdem verwendet die von der Eigenschaft "Standard" zurückgegebene Kodierung einen Best-Fit-Fallback (d. h. die Kodierung ist völlig verkorkst, so dass man sie nicht wieder zurückkodieren kann) um nicht unterstützte Zeichen auf Zeichen abzubilden, die von der Codepage unterstützt werden. Aus diesen Gründen wird die Verwendung der Standardkodierung nicht empfohlen. Um sicherzustellen, dass kodierte Bytes richtig dekodiert werden, sollten Sie eine Unicode-Kodierung verwenden, wie z. B. UTF8Encoding oder UnicodeEncoding. Sie könnten auch ein übergeordnetes Protokoll verwenden, um sicherzustellen, dass für die Kodierung und Dekodierung das gleiche Format verwendet wird.
Um zu prüfen, welche Kodierung standardmäßig verwendet wird, verwenden Sie Encoding.Default.WindowsCodePage
(1250 in meinem Fall - und leider gibt es keine vordefinierte Klasse für die CP1250-Kodierung, aber das Objekt könnte abgerufen werden als Encoding.GetEncoding(1250)
).
...UTF-8/UTF-16LE Kodierung sollte stattdessen verwendet werden...
Encoding.ASCII
in der meistbewerteten Antwort ist 7bit, also funktioniert es in meinem Fall auch nicht:
byte[] pass = Encoding.ASCII.GetBytes("šarže");
Console.WriteLine(Encoding.ASCII.GetString(pass)); // ?ar?e
Der Empfehlung von Microsoft folgend:
var utf8 = new UTF8Encoding();
byte[] pass = utf8.GetBytes("šarže");
Console.WriteLine(utf8.GetString(pass)); // šarže
Encoding.UTF8
ist eine Instanz der UTF-8-Kodierung und kann auch direkt oder als
var utf8 = Encoding.UTF8 as UTF8Encoding;
Encoding.Unicode
ist für die String-Darstellung im Speicher beliebt, weil es feste 2 Bytes pro Zeichen verwendet, so dass man zum n-ten Zeichen in konstanter Zeit auf Kosten von mehr Speicherverbrauch springen kann: es ist UTF-16LE. In MSVC# sind die *.cs-Dateien standardmäßig in UTF-8 BOM und String-Konstanten in ihnen werden zur Kompilierzeit in UTF-16LE konvertiert (siehe @OwnagelsMagic Kommentar), aber es ist NICHT als Standard definiert: viele Klassen wie StreamWriter verwendet standardmäßig UTF-8.
...aber es wird nicht immer benutzt
Die Standardkodierung ist irreführend: .NET verwendet überall UTF-8 (einschließlich der im Quellcode fest kodierten Zeichenfolgen) und UTF-16LE ( Encoding.Unicode
), um Zeichenfolgen im Speicher zu speichern, aber Windows verwendet tatsächlich 2 andere Nicht-UTF8-Standardwerte: ANSI-Codepage (für GUI-Anwendungen vor .NET) und OEM-Codepage (auch bekannt als DOS-Standard). Diese unterscheiden sich von Land zu Land (z. B. verwendet die tschechische Windows-Ausgabe CP1250 und CP852) und sind oft in den Windows-API-Bibliotheken fest einkodiert. Wenn Sie also einfach UTF-8 für die Konsole einstellen, indem Sie chcp 65001
(wie es .NET implizit tut und so tut, als wäre es der Standard) und einen lokalisierten Befehl (wie ping) ausführt, funktioniert es in der englischen Version, aber in der Tschechischen Republik erhält man Tofu-Text.
Ich möchte meine Erfahrungen aus der Praxis weitergeben: Ich habe eine WinForms-Anwendung erstellt, die Git-Skripte für Lehrer anpasst. Die Ausgabe wird im Hintergrund anynchron durch einen Prozess erhalten beschrieben von Microsoft als (fettgedruckter Text von mir hinzugefügt):
Das Wort "Hülle" in diesem Zusammenhang (UseShellExecute) bezieht sich auf eine grafische Shell (ähnlich der Windows-Shell), ANSI CP ) und nicht mit Befehlsshells (z. B. bash oder sh), OEM-CP ) und ermöglicht es den Benutzern, grafische Anwendungen zu starten oder Dokumente zu öffnen mit fehlerhafter Ausgabe in Nicht-US-Umgebung .
Die grafische Benutzeroberfläche ist also auf UTF-8, der Prozess auf CP1250 und die Konsole auf 852 voreingestellt. Die Ausgabe erfolgt also in 852, interpretiert als UTF-8, interpretiert als CP1250. Ich erhielt Tofu-Text, aus dem ich aufgrund der doppelten Konvertierung nicht auf die ursprüngliche Codepage schließen konnte. Ich habe mir eine Woche lang die Haare gerauft, um herauszufinden, wie man explizit UTF-8 für das Prozessskript einstellt und die Ausgabe von CP1250 in UTF-8 im Hauptthread konvertiert. Jetzt funktioniert es hier in Osteuropa, aber in Westeuropa verwendet Windows 1252. ANSI CP ist nicht einfach zu bestimmen, da viele Befehle wie systeminfo
sind ebenfalls lokalisiert und andere Methoden unterscheidet sich von Version zu Version : In einer solchen Umgebung ist die zuverlässige Darstellung nationaler Schriftzeichen fast unmöglich.
Bis zur Hälfte des 21. Jahrhunderts sollten Sie daher KEINE "Standard-Codepage" und stellen sie ausdrücklich (wenn möglich in UTF-8 oder UTF-16LE).