2012-04-03 8 views
8

Also habe ich einige Probleme mit der Zeichenkodierung. Als ich legte die folgenden zwei Zeichen in eine UTF32 codierten Textdatei:UTF32 und C# Probleme

und dann auf sie diesen Code ausführen:

System.IO.StreamReader streamReader = 
    new System.IO.StreamReader("input", System.Text.Encoding.UTF32, false); 
System.IO.StreamWriter streamWriter = 
    new System.IO.StreamWriter("output", false, System.Text.Encoding.UTF32); 

streamWriter.Write(streamReader.ReadToEnd()); 

streamWriter.Close(); 
streamReader.Close(); 

ich:

鸕 
鸕 

(gleiche Zeichen zweimal, dh die Eingabedatei! = Ausgabe)

Ein paar Dinge, die helfen könnten: Hex für das erste Zeichen:

15 9E 02 00

Und zum zweiten:

15 9E 00 00

ich gedit für die Textdatei Erstellung verwenden, Mono für die C# und ich benutze Ubuntu.

Es ist auch egal, wenn ich die Codierung für die Eingabe- oder Ausgabedatei angeben, es mag es einfach nicht, wenn es in UTF32-Codierung ist. Es funktioniert, wenn die Eingabedatei in UTF-8-Codierung ist.

Die Eingabedatei ist wie folgt:

FF FE 00 00 15 9E 02 00 0A 00 00 00 15 9E 00 00 0A 00 00 00

Ist es ein Fehler, oder ist es gerade ich?

Danke!

+0

Encoding der Ausgabedatei? –

+0

Drucken Sie das Ergebnis von 'streamReader.ReadToEnd()' aus. – leppie

+0

@ L.B - Ändern hilft nicht – AStupidNoob

Antwort

5

K, also habe ich herausgefunden, ich denke, es scheint jetzt zu funktionieren. Stellt sich heraus, da die Codes für die Zeichen waren 15 9E 02 00 und 15 9E 00 00, dann gibt es keine Möglichkeit, dass sie in einem einzigen UTF-16 char gehalten werden können. Stattdessen verwendet UTF16 stattdessen diese Ersatzpaare, bei denen zwei verschiedene Zeichen als ein "Element" fungieren. Um Elemente zu erhalten, können wir verwenden:

StringInfo.GetTextElementEnumerator(string fred); 

und dies gibt eine Zeichenfolge mit den Ersatzpaaren zurück. Behandle es als ein Zeichen.

Siehe hier:

http://msdn.microsoft.com/en-us/library/system.globalization.stringinfo.aspx

http://msdn.microsoft.com/en-us/library/system.globalization.textelementenumerator.gettextelement.aspx

Hoffe, es hilft jemand: D

0

Beim Schreiben geben Sie nicht UTF-32 an, daher wird standardmäßig Encoding.UTF8 verwendet.

Von MSDN:

Dieser Konstruktor erstellt eine Stream mit UTF-8-Codierung ohne Byte-Order Mark (BOM), so dass ihre GetPreamble Methode gibt ein leeres Byte Array. Um einen StreamWriter unter Verwendung der UTF-8-Codierung und einer Stückliste zu erstellen, verwenden Sie die Verwendung eines Konstruktors, der die Codierung angibt, z. B. StreamWriter (String, Boolean, Encoding).

+0

Das scheint nicht das Problem zu sein. Ich habe die Frage aktualisiert, um Verwirrung zu vermeiden. Trotzdem trotzdem danke! – AStupidNoob

0

Ich denke, Sie müssen die gleiche Codierung (Encoding.UTF32) auch für Ihre StreamWriter angeben.

EDIT:

Normalerweise ist es nicht zwischen UTF Codepages benötigt, aber ich würde dies auch versuchen:

Encoding utf8 = Encoding.UTF8; 
Encoding utf32 = Enconding.UTF32; 
byte[] utf8Bytes = utf8.GetBytes(yourText); 
byte[] utf32Bytes = Encoding.Convert(utf8, utf32, utf8Bytes); 
string utf32Text = iso.GetString(utf32Text); 
+0

Ich habe: D, ich habe gerade die Frage bearbeitet.Es wäre auch nicht wirklich wichtig, da jedes UTF-32-Zeichen in UTF-8 oder einer beliebigen Unicode-Kodierung ausgedrückt werden kann. AFAIK jedenfalls. – AStupidNoob

+0

@AStupidNoob Ich habe gerade Ihre aktualisierte Antwort und Ihre Kommentare gelesen. Wenn Sie wissen, welche Kodierung die gelesene Datei ist und es anders als UTF32 ist, dann müssen Sie sie in ihrer ursprünglichen Kodierung lesen und sie in die eigene konvertieren, bevor Sie sie schreiben. – Dummy01

+0

Vielen Dank für Ihre Hilfe. Ich habe Ihren Vorschlag versucht, aber ich konnte es nicht funktionieren. Außerdem dachte ich, der gesamte Zweck von StringReaders und StringWriters bestand darin, zwischen Codierungen zu konvertieren. Vielleicht nicht dann. – AStupidNoob

1

Ich versuchte dies und es funktioniert gut auf meinem PC.

System.IO.StreamReader streamReader = new System.IO.StreamReader("input", true); 
System.IO.StreamWriter streamWriter = new System.IO.StreamWriter("output", false); 

streamWriter.Write(streamReader.ReadToEnd()); 

streamWriter.Close(); 
streamReader.Close(); 

Vielleicht ist der Text, den Sie denken, ist in UTF32 ist nicht.

+0

Verwenden Sie Visual Studio/Windows? Es könnte nur Mono sein, wenn nicht. Ich werde andere Programme versuchen, um sicherzustellen, dass es in der Tat UTF32 ist, sieht es sicherlich in einem Hex-Editor aus ... – AStupidNoob

+0

Ok, viel Glück. Aber Ihr Code hat auch auf meinem PC eine falsche Ausgabe erzeugt. –

+1

Oh, Entschuldigung, ich habe die Änderung in Ihrem Code nicht bemerkt. In anderen Nachrichten, die Verwendung von Visual Studio 2012 Beta ergab die korrekte Ausgabe mit meinem Code ... – AStupidNoob

0

Vom Abschnitt Hinweise MSDN für StreamReader's constructor:

Dieser Konstruktor initialisiert die Codierung, wie durch die Codierungs Parameter angegeben, und die interne Puffergröße auf 1024 Bytes. Das StreamReader-Objekt versucht, die Codierung zu erkennen, indem es die ersten drei Bytes des Streams betrachtet. Es erkennt UTF-8, Little-Endian-Unicode und Big-Endian-Unicode-Text automatisch, wenn die Datei mit den entsprechenden Byte-Reihenfolgezeichen startet. Andernfalls wird die vom Benutzer bereitgestellte Codierung verwendet. Weitere Informationen finden Sie in der Encoding.GetPreamble-Methode. Informationen hierzu finden Sie unter .

Sehr wahrscheinlich die Byte-Reihenfolge Zeichen am Anfang Ihrer Datei angibt, tatsächlich UTF-16 (oder etwas), und es ist so nicht Ihre explizit angegeben UTF-32-Codierung.

+0

Sicher, warum nicht, ich werde versuchen, einige andere Programme zu verwenden, um sicherzustellen, dass ich die richtige Stückliste bekomme. – AStupidNoob

+0

@AStupidNoob Es sieht aus wie es gibt eine Konstruktorüberladung, die die Stückliste nicht durch Hinzufügen eines booleschen Parameters betrachten, könnte versuchen, dass, wenn Sie kein anderes Programm zur Hand haben, um zu überprüfen. – Tanzelax

+0

Richtig, ich hätte gedacht, dass die Angabe der Codierung sichergestellt hätte, dass es verwendet wurde, offensichtlich nicht dann. Ich habe jedoch versucht, Windows dafür zu verwenden und es hat funktioniert. Aber ich konnte seine UTF32-Ausgabe nicht überprüfen, da ich keine Windows-Programme habe, die gut mit UTF32 funktionieren, also tauschte ich sie gegen UTF8 aus. – AStupidNoob