Converting string to byte array in C#

2019-01-01 06:45发布

问题:

I\'m quite new to C#. I\'m converting something from VB into C#. Having a problem with the syntax of this statement:

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

I then see the following errors:

Argument 1: cannot convert from \'object\' to \'byte[]\'

The best overloaded method match for \'System.Text.Encoding.GetString(byte[])\' has some invalid arguments

I tried to fix the code based on this post, but still no success

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

Any suggestions?

回答1:

If you already have a byte array then you will need to know what type of encoding was used to make it into that byte array.

For example, if the byte array was created like this:

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

You will need to turn it back into a string like this:

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

If you can find in the code you inherited, the encoding used to create the byte array then you should be set.



回答2:

First of all, add the System.Text namespace

using System.Text;

Then use this code

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

Hope to fix it!



回答3:

Also you can use an Extension Method to add a method to the string type as below:

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

And use it like below:

string foo = \"bla bla\";
byte[] result = foo.ToByteArray();


回答4:

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);
}


回答5:

var result = System.Text.Encoding.Unicode.GetBytes(text);


回答6:

use this

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


回答7:

The following approach will work only if the chars are 1 byte. (Default unicode will not work since it is 2 bytes)

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;
}

Keeping it simple



回答8:

A refinement to JustinStolle\'s edit (Eran Yogev\'s use of BlockCopy).

The proposed solution is indeed faster than using Encoding. Problem is that it doesn\'t work for encoding byte arrays of uneven length. As given, it raises an out-of-bound exception. Increasing the length by 1 leaves a trailing byte when decoding from string.

For me, the need came when I wanted to encode from DataTable to JSON. I was looking for a way to encode binary fields into strings and decode from string back to byte[].

I therefore created two classes - one that wraps the above solution (when encoding from strings it\'s fine, because the lengths are always even), and another that handles byte[] encoding.

I solved the uneven length problem by adding a single character that tells me if the original length of the binary array was odd (\'1\') or even (\'0\')

As follows:

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;
    }
}


回答9:

Does anyone see any reason why not to do this?

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


回答10:

If the result of, \'searchResult.Properties [ \"user\" ] [ 0 ]\', is a string:

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

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

}

The key point being that converting a string to a byte [] can be done using LINQ:

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

And the inverse:

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


回答11:

This question has been answered sufficiently many times, but with C# 7.2 and the introduction of the Span type, there is a faster way to do this in unsafe code:

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));
        }
    }
}

Keep in mind that the bytes represent a UTF-16 encoded string (called \"Unicode\" in C# land).

Some quick benchmarking shows that the above methods are roughly 5x faster than their Encoding.Unicode.GetBytes(...)/GetString(...) implementations for medium sized strings (30-50 chars), and even faster for larger strings. These methods also seem to be faster than using pointers with Marshal.Copy(..) or Buffer.MemoryCopy(...).