it-swarm.com.de

Konvertierung von String in Byte-Array in C #

Ich bin ziemlich neu in C #. Ich konvertiere etwas von VB in C #. Probleme mit der Syntax dieser Anweisung haben:

if ((searchResult.Properties["user"].Count > 0))
{
    profile.User = System.Text.Encoding.UTF8.GetString(searchResult.Properties["user"][0]);
}

Ich sehe dann die folgenden Fehler:

Argument 1: Konvertierung von 'Objekt' nach 'Byte []' nicht möglich

Die beste überladene Methode für 'System.Text.Encoding.GetString (byte [])' enthält einige ungültige Argumente

Ich habe versucht, den Code basierend auf this post zu korrigieren, aber immer noch keinen Erfolg

string User = Encoding.UTF8.GetString("user", 0);

Irgendwelche Vorschläge?

436
nouptime

Wenn Sie bereits über ein Byte-Array verfügen, müssen Sie wissen, welche Art von Codierung verwendet wurde, um es in dieses Byte-Array aufzunehmen.

Wenn das Byte-Array beispielsweise so erstellt wurde:

byte[] bytes = Encoding.ASCII.GetBytes(someString);

Sie müssen es wieder in eine Zeichenfolge umwandeln:

string someString = Encoding.ASCII.GetString(bytes);

Wenn Sie in dem von Ihnen geerbten Code die zum Erstellen des Bytearrays verwendete Codierung finden können, sollten Sie festgelegt werden.

725
Timothy Randall

Fügen Sie zunächst den System.Text-Namespace hinzu

using System.Text;

Dann benutze diesen Code

string input = "some text"; 
byte[] array = Encoding.ASCII.GetBytes(input);

Hoffe, es zu beheben!

81
Shridhar

Sie können auch eine Extension-Methode verwenden, um eine Methode zum string-Typ hinzuzufügen:

static class Helper
{
   public static byte[] ToByteArray(this string str)
   {
      return System.Text.Encoding.ASCII.GetBytes(str);
   }
}

Und benutze es wie folgt:

string foo = "bla bla";
byte[] result = foo.ToByteArray();
33
combo_ci
static byte[] GetBytes(string str)
{
     byte[] bytes = new byte[str.Length * sizeof(char)];
     System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
     return bytes;
}

static string GetString(byte[] bytes)
{
     char[] chars = new char[bytes.Length / sizeof(char)];
     System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
     return new string(chars);
}
20
Eran Yogev
var result = System.Text.Encoding.Unicode.GetBytes(text);
14

benutze das 

byte[] myByte= System.Text.ASCIIEncoding.Default.GetBytes(myString);
10
alireza amini

Der folgende Ansatz funktioniert nur, wenn die Zeichen 1 Byte sind. (Der Standard-Unicode funktioniert nicht, da er aus 2 Byte besteht.)

public static byte[] ToByteArray(string value)
{            
    char[] charArr = value.ToCharArray();
    byte[] bytes = new byte[charArr.Length];
    for (int i = 0; i < charArr.Length; i++)
    {
        byte current = Convert.ToByte(charArr[i]);
        bytes[i] = current;
    }

    return bytes;
}

Einfach halten

9
Mandar Sudame

Eine Verbesserung der Bearbeitung von JustinStolle (Eran Yogevs Verwendung von BlockCopy).

Die vorgeschlagene Lösung ist in der Tat schneller als die Verwendung von Encoding . Das Problem ist, dass sie nicht für das Codieren von Byte-Arrays mit ungleichmäßiger Länge arbeitet length by 1 hinterlässt bei der Decodierung von string ein nachfolgendes Byte.

Für mich bestand die Notwendigkeit, als ich von DataTable in JSON..__ codieren wollte. Ich suchte nach einer Möglichkeit, binäre Felder in Strings zu codieren und von String zurück nach byte[] zu decodieren.

Ich habe daher zwei Klassen erstellt - eine, die die obige Lösung umschließt (wenn aus Strings codiert wird, ist dies in Ordnung, da die Längen immer gerade sind) und eine andere, die byte[]-Codierung behandelt.

Ich habe das Problem der ungleichmäßigen Länge durch Hinzufügen eines einzelnen Zeichens gelöst, das angibt, ob die ursprüngliche Länge des binären Arrays ungerade ('1') oder gerade ('0') war.

Wie folgt:

public static class StringEncoder
{
    static byte[] EncodeToBytes(string str)
    {
        byte[] bytes = new byte[str.Length * sizeof(char)];
        System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
        return bytes;
    }
    static string DecodeToString(byte[] bytes)
    {
        char[] chars = new char[bytes.Length / sizeof(char)];
        System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
        return new string(chars);
    }
}

public static class BytesEncoder
{
    public static string EncodeToString(byte[] bytes)
    {
        bool even = (bytes.Length % 2 == 0);
        char[] chars = new char[1 + bytes.Length / sizeof(char) + (even ? 0 : 1)];
        chars[0] = (even ? '0' : '1');
        System.Buffer.BlockCopy(bytes, 0, chars, 2, bytes.Length);

        return new string(chars);
    }
    public static byte[] DecodeToBytes(string str)
    {
        bool even = str[0] == '0';
        byte[] bytes = new byte[(str.Length - 1) * sizeof(char) + (even ? 0 : -1)];
        char[] chars = str.ToCharArray();
        System.Buffer.BlockCopy(chars, 2, bytes, 0, bytes.Length);

        return bytes;
    }
}
6
user4726577

Hat jemand einen Grund, warum das nicht zu tun?

mystring.Select(Convert.ToByte).ToArray()
4
Lomithrani

Wenn das Ergebnis von 'searchResult.Properties ["user"] [0]' eine Zeichenfolge ist:

if ( ( searchResult.Properties [ "user" ].Count > 0 ) ) {

   profile.User = System.Text.Encoding.UTF8.GetString ( searchResult.Properties [ "user" ] [ 0 ].ToCharArray ().Select ( character => ( byte ) character ).ToArray () );

}

Der entscheidende Punkt ist, dass das Konvertieren eines Strings in ein Byte [] mit LINQ erfolgen kann:

.ToCharArray ().Select ( character => ( byte ) character ).ToArray () )

Und das Gegenteil:

.Select ( character => ( char ) character ).ToArray () )
3
Janus

Diese Frage wurde ausreichend oft genug beantwortet, aber mit C # 7.2 und der Einführung des Typs Span gibt es einen schnelleren Weg, dies in unsicherem Code zu tun:

public static class StringSupport
{
    private static readonly int _charSize = sizeof(char);

    public static unsafe byte[] GetBytes(string str)
    {
        if (str == null) throw new ArgumentNullException(nameof(str));
        if (str.Length == 0) return new byte[0];

        fixed (char* p = str)
        {
            return new Span<byte>(p, str.Length * _charSize).ToArray();
        }
    }

    public static unsafe string GetString(byte[] bytes)
    {
        if (bytes == null) throw new ArgumentNullException(nameof(bytes));
        if (bytes.Length % _charSize != 0) throw new ArgumentException($"Invalid {nameof(bytes)} length");
        if (bytes.Length == 0) return string.Empty;

        fixed (byte* p = bytes)
        {
            return new string(new Span<char>(p, bytes.Length / _charSize));
        }
    }
}

Beachten Sie, dass die Bytes eine UTF-16-codierte Zeichenfolge darstellen (in C # land "Unicode" genannt).

Ein schnelles Benchmarking zeigt, dass die obigen Methoden etwa fünfmal schneller sind als ihre Implementierungen von Encoding.Unicode.GetBytes (...)/GetString (...) für mittelgroße Zeichenfolgen (30-50 Zeichen) und noch schneller für größere Zeichenfolgen. Diese Methoden scheinen auch schneller zu sein als die Verwendung von Zeigern mit Marshal.Copy (..) oder Buffer.MemoryCopy (...).

1
returnsvoid

Aufbauend auf ALis Antwort würde ich eine Erweiterungsmethode empfehlen, mit der Sie optional die Codierung übergeben können, die Sie verwenden möchten:

using System.Text;
public static class StringExtensions
{
    /// <summary>
    /// Creates a byte array from the string, using the 
    /// System.Text.Encoding.Default encoding unless another is specified.
    /// </summary>
    public static byte[] ToByteArray(this string str, Encoding encoding = Encoding.Default)
    {
        return encoding.GetBytes(str);
    }
}

Und benutze es wie folgt:

string foo = "bla bla";

// default encoding
byte[] default = foo.ToByteArray();

// custom encoding
byte[] unicode = foo.ToByteArray(Encoding.Unicode);
0
Dan Sinclair

Diese Arbeit für mich, danach konnte ich mein Bild in ein Bytea-Feld in meiner Datenbank stellen.

using (MemoryStream s = new MemoryStream(DirEntry.Properties["thumbnailphoto"].Value as byte[]))
{
    return s.ToArray();
}
0
user10863293