web-dev-qa-db-ja.com

C#で文字列をバイト配列に変換する

私はC#が全く初めてです。私は何かをVBからC#に変換しています。この文の構文に問題があります。

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

次のようなエラーが表示されます。

引数1: 'object'から 'byte []'に変換できません

'System.Text.Encoding.GetString(byte [])'に最も適したオーバーロードメソッドの一致

this postに基づいてコードを修正しようとしましたが、それでも成功しません

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

助言がありますか?

436
nouptime

すでにバイト配列がある場合は、そのバイト配列にするためにどのタイプのエンコードが使用されているかを知る必要があります。

たとえば、バイト配列が次のように作成されたとします。

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

このように文字列に戻す必要があります。

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

継承したコードの中に、バイト配列を作成するために使用されたエンコーディングが見つかったら、それを設定する必要があります。

725
Timothy Randall

まず最初に、System.Text名前空間を追加してください。

using System.Text;

それからこのコードを使ってください

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

それを修正することを願っています!

81
Shridhar

以下のように 拡張メソッド を使ってstring型にメソッドを追加することもできます。

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

そしてそれを以下のように使います。

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

これを使って 

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

次の方法は、文字数が1バイトの場合にのみ機能します。 (デフォルトのUnicodeは2バイトなので動作しません)

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

シンプルに保つ

9
Mandar Sudame

JustinStolleの編集(Eran YogevによるBlockCopyの使用)の改良。

提案された解決策は、実際にはEncodingを使うよりも速い。問題は、長さが不定のバイト配列をエンコードするのにはうまくいかないことである。長さを1つ増やすと、文字列からデコードするときに末尾のバイトが残ります。

私にとっては、DataTableからJSONにエンコードしたい時に必要となりました。バイナリフィールドを文字列にエンコードし、文字列からbyte[]にデコードする方法を探していました。

そこで私は2つのクラスを作成しました - 1つは上記の解決策をラップするものです(文字列からエンコードするときは長さが常に偶数であるため問題ありません)、そしてもう1つはbyte[]エンコードを処理します。

バイナリ配列の元の長さが奇数( '1')か偶数( '0')かを示す単一の文字を追加することで、長さの不均等の問題を解決しました。

次のように:

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

誰もがこれをしない理由を見ますか?

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

'searchResult.Properties ["user"] [0]'の結果が文字列の場合、

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

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

}

重要なのは、文字列をbyte []に​​変換することはLINQを使ってできるということです。

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

そしてその逆:

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

この質問は何度も回答されてきましたが、C#7.2とSpanタイプの導入により、安全でないコードでこれを行うより速い方法があります。

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

バイトはUTF-16でエンコードされた文字列(C#ランドでは「Unicode」と呼ばれる)を表すことに注意してください。

いくつかの簡単なベンチマークは、上記のメソッドが中サイズの文字列(30〜50文字)のEncoding.Unicode.GetBytes(...)/ GetString(...)の実装よりもおよそ5倍高速であることを示します。これらのメソッドは、Marshal.Copy(..)またはBuffer.MemoryCopy(...)でポインタを使用するよりも速いようです。

1
returnsvoid

ALiの答え を構築して、私はあなたが使いたいエンコーディングをオプションで渡すことを可能にする拡張メソッドをお勧めします。

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

そしてそれを以下のように使います。

string foo = "bla bla";

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

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

私のためにこの仕事は、その後私は私のデータベースのbyteaフィールドに私の写真を入れて変換することができました。

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