1

オブジェクトをバイト配列に変換しようとすると、奇妙な配列が表示されます。これはコードです:

        using (MemoryStream ms = new MemoryStream())
        {
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, obj);
            Console.WriteLine(ByteArrayToString(ms.ToArray()));
        }
//int obj = 50;

//string ByteArrayToString(byte[] byteArr) the functionality of this method is pretty obvious

結果は次のとおりです。

"00 01 00 00 00 FF FF FF FF 01 00 00 00 00 00 00 00 04 01 00 00 00 0C 53 79 73 74 65 6D 2E 49 6E 74 33 32 01 00 00 00 07 6D 5F 76 61 6C 75 65 00 08 32 00 00 00 0B "

誰かが私に理由を説明できますか?:)最適な結果は「32 000000」のみである必要があります。

4

5 に答える 5

8

シリアライザーは、データを逆シリアル化するのに十分な情報を提供する必要があるため、シリアル化されるオブジェクトに関するメタデータを含める必要があります。具体的には、

53 79 73 74 65 6D 2E 49 6E 74 33 32

一部の略System.Int32

BinaryWriter代わりにとそのメソッドを使用するとWrite(Int32)、目的の効果が得られます。メモリストリームには、整数から4バイトだけが含まれます。Int32ストリームに書き込みを行ったことを知らなければ、逆シリアル化することはできません。

于 2012-05-07T16:41:02.320 に答える
2

シリアル化をメモリ形式BinaryFormatterのオブジェクトと混同しています。ストリームに書き込まれるのは、の実装の詳細にすぎず、を使用しないプロセス間通信には依存しないでください。BinaryFormatterBinaryFormatter

組み込み型のバイト表現を探している場合は、を使用しますBitConverter.GetBytes(文字列の場合は適切なを使用しますEncoding.GetBytes)。

于 2012-05-07T16:41:05.403 に答える
1

シリアル化されたバイト配列には、データ自体と型情報の両方が含まれます。そのため、予想よりも多くの情報を取得できます。これは、後で逆シリアル化するために必要です。

于 2012-05-07T16:49:16.757 に答える
0

結果に追加されるのは、BinaryFormatterオブジェクトです。int obj = 50を出力するだけでなく、BinaryFormatterに含まれるすべてのものも出力します。

于 2012-05-07T16:39:10.267 に答える
0

シリアル化プロセスでは、余分なバイトを使用してタイプに関する情報を格納します。これは、シリアル化されたデータが同じタイプの同じオブジェクトに逆シリアル化されることを保証する唯一の方法です。自分が何をしているのかを絶対に確信していて、余分なバイトを避けたい場合は、独自のシリアル化を使用して、フォーマッターとシリアライザーを作成できます。これは非常に複雑です。または、マーシャリングを使用できます。

var size = Marshal.SizeOf(your_object);
// Both managed and unmanaged buffers required.
var bytes = new byte[size];
var ptr = Marshal.AllocHGlobal(size);
// Copy object byte-to-byte to unmanaged memory.
Marshal.StructureToPtr(font.LogFont, ptr, false);
// Copy data from unmanaged memory to managed buffer.
Marshal.Copy(ptr, bytes, 0, size);
// Release unmanaged memory.
Marshal.FreeHGlobal(ptr);

そして、バイトをオブジェクトに変換するには:

var bytes = new byte[size];
var ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(bytes, 0, ptr, size);
var your_object = (YourType)Marshal.PtrToStructure(ptr, typeof(YourType));
Marshal.FreeHGlobal(ptr);

これは非常に遅く、ほとんどの場合使用するのは安全ではありませんが、シリアル化を実装せず、[Serializable]属性を使用せずに、オブジェクトをbyte[]に厳密に変換する最も簡単な方法です。

于 2013-10-19T16:08:32.193 に答える