Frage

Ich muß in die Lage, eine beliebige Texteingabe zu nehmen, die auf eine Byte-Reihenfolge Markierung (BOM) konnten seine Codierung zu markieren, und gibt es als ASCII. Wir haben einige alte Werkzeuge, die nicht verstehen Stücklisten und ich brauche sie nur ASCII-Daten zu senden.

Nun, ich habe gerade getan, um diesen Code zu schreiben, und ich kann einfach nicht ganz die Ineffizienz hier glauben. Vier Kopien der Daten, nicht zu erwähnen, keine Zwischenpuffer intern in Stream. Gibt es einen besseren Weg, dies zu tun?

// i_fileBytes is an incoming byte[]

string unicodeString = new StreamReader(new MemoryStream(i_fileBytes)).ReadToEnd();
byte[] unicodeBytes  = Encoding.Unicode.GetBytes(unicodeString.ToCharArray());
byte[] ansiBytes     = Encoding.Convert(Encoding.Unicode, Encoding.ASCII, unicodeBytes);
string ansiString    = Encoding.ASCII.GetString(ansiBytes);

Ich brauche die Stream (), weil es einen internen BOM-Detektor hat die Codierung zu wählen, den Rest der Datei zu lesen. Dann wird der Rest ist nur, um es in das endgültige ASCII-String zu machen zu konvertieren.

Gibt es einen besseren Weg, dies zu tun?

War es hilfreich?

Lösung

Wenn Sie i_fileBytes im Speicher bereits haben, können Sie einfach überprüfen, ob es mit einem BOM beginnt, und dann konvertieren entweder das ganzes es oder einfach nur das Bit nach dem BOM Encoding.Unicode.GetString verwenden. (Verwenden Sie die Überlastung, die Sie einen Index und Länge angeben können.)

So wie Code:

int start = (i_fileBytes[0] == 0xff && i_fileBytes[1] == 0xfe) ? 2 : 0;
string text = Encoding.Unicode.GetString(i_fileBytes, start, i_fileBytes.Length-start);

Beachten Sie, dass das nimmt sie eine wirklich Little-Endian UTF-16-Codierung, jedoch. Wenn Sie wirklich die Codierung zuerst erfassen müssen, können Sie entweder neu implementieren, was Stream tut, oder vielleicht nur ein Stream von den ersten (sagen wir) 10 Bytes bauen, und die CurrentEncoding Eigenschaft verwenden, um herauszufinden, was Sie sollte für die Codierung verwendet werden.

EDIT: Nun, wie für die Umwandlung in ASCII - wenn man wirklich nur als einen .NET-String benötigt, dann vermutlich alles, was Sie tun möchten, ist keine Nicht-ASCII-Zeichen mit ersetzen „?“ oder etwas ähnliches. (Alternativ könnte es besser sein, eine Ausnahme zu werfen ... das ist bis zu Ihnen, natürlich.)

EDIT: Beachten Sie, dass, wenn die Codierung zu erfassen, wäre es eine gute Idee sein, ein einziges Mal nur callen Read() ein Zeichen zu lesen. Rufen Sie nicht ReadToEnd() wie durch 10 Bytes als eine beliebige Menge an Daten sammeln, könnte es Mitte Zeichen enden. Ich weiß nicht, ob ohne Weiteres, dass eine Ausnahme auslösen würde, aber es hat keine Vorteile sowieso ...

Andere Tipps

System.Text.Encoding.ASCII.GetBytes(new StreamReader(new MemoryStream(i_fileBytes)).ReadToEnd())

Das sollte ein paar Umläufe speichern.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top