Frage

Ich arbeite an seriell Port, Senden und Daten zu einem gewissen Hardware bei 8bit Daten empfangen. Ich möchte es als Zeichenfolge speichern, den Vergleich zu erleichtern, und voreingestellten Daten werden als String oder Hex-Format in XML-Datei gespeichert. Ich fand heraus, dass nur dann, wenn Encoding.Default verwendet, die ANSI-Codierung ist dann die 8-Bit-Daten richtig umgewandelt werden und leicht reversibel. ASCII-Kodierung wird funktioniert nur für 7-Bit-Daten und UTF8 oder UTF7 nicht funktioniert auch nicht gut, da ich einige Zeichen 1-255 bin mit. Encoding.Default wäre ganz gut, aber ich lese auf MSDN, dass es auf OS-Codepage-Einstellung abhängig ist, das heißt, es sich anders verhalten könnte auf verschiedenen Codepage konfiguriert ist. Ich benutze GetBytes () und GetString ausführlich die Codierung, möchte aber eine ausfallsichere und tragbare Methode, die die ganze Zeit bei jeder Konfiguration funktioniert. Jede Idee oder besserer Vorschlag für das?

War es hilfreich?

Lösung

Latin-1 aka ISO-8859-1 aka Codepage 28591 ist eine nützliche Codepage für dieses Szenario, da es Werte im Bereich von 128 bis 255 unverändert abbildet. Die folgenden sind austauschbar:

Encoding.GetEncoding(28591)
Encoding.GetEncoding("Latin1")
Encoding.GetEncoding("iso-8859-1")

Der folgende Code zeigt die Tatsache, dass für Latin1, im Gegensatz zu Encoding.Default, alle Zeichen im Bereich von 0 bis 255 unverändert abgebildet werden:

static void Main(string[] args)
{

    Console.WriteLine("Test Default Encoding returned {0}", TestEncoding(Encoding.Default));
    Console.WriteLine("Test Latin1 Encoding returned {0}", TestEncoding(Encoding.GetEncoding("Latin1")));
    Console.ReadLine();
    return;
}

private static bool CompareBytes(char[] chars, byte[] bytes)
{
    bool result = true;
    if (chars.Length != bytes.Length)
    {
        Console.WriteLine("Length mismatch {0} bytes and {1} chars" + bytes.Length, chars.Length);
        return false;
    }
    for (int i = 0; i < chars.Length; i++)
    {
        int charValue = (int)chars[i];
        if (charValue != (int)bytes[i])
        {
            Console.WriteLine("Byte at index {0} value {1:X4} does not match char {2:X4}", i, (int) bytes[i], charValue);
            result = false;
        }
    }
    return result;
}
private static bool TestEncoding(Encoding encoding)
{
    byte[] inputBytes = new byte[256];
    for (int i = 0; i < 256; i++)
    {
        inputBytes[i] = (byte) i;
    }

    char[] outputChars = encoding.GetChars(inputBytes);
    Console.WriteLine("Comparing input bytes and output chars");
    if (!CompareBytes(outputChars, inputBytes)) return false;

    byte[] outputBytes = encoding.GetBytes(outputChars);
    Console.WriteLine("Comparing output bytes and output chars");
    if (!CompareBytes(outputChars, outputBytes)) return false;

    return true;
}

Andere Tipps

Warum stattdessen nicht nur ein Array von Bytes verwenden? Es würde keine der Codierung Probleme haben Sie mit dem Text Ansatz wahrscheinlich leiden sind.

Ich glaube, Sie sollten stattdessen einen Byte-Array verwenden. Zum Vergleich können Sie eine Methode wie folgt verwenden:

static bool CompareRange(byte[] a, byte[] b, int index, int count)
{
    bool res = true;
    for(int i = index; i < index + count; i++)
    {
        res &= a[i] == b[i];
    }
    return res;
}

Mit der hebräischen Codepage für Windows-1255. Sein 8-Bit.
Encoding enc = Encoding.GetEncoding ( "windows-1255");

Ich missunderstod Sie, wenn Sie schrieb "1-255", Sie dachten, wo man Zeichen in Codepage 1255 refereing.

Sie können Base64-Kodierung von Byte-String und zurück zu konvertieren. Keine Probleme mit dem Code-Seiten oder seltsamen Zeichen auf diese Weise, und es wird mehr Platz spar als hex.

byte[] toEncode; 
string encoded = System.Convert.ToBase64String(toEncode);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top