質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

1347閲覧

list<string[]> のbyte[]へのシリアライズ デシリアライズの方法

RC46

総合スコア7

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2021/05/10 15:57

list<string[]> のbyte[]へのシリアライズ デシリアライズの方法についてお聞したいです
ソケット通信をつかって、クラインアント側からリスト型データを送信したいと思っています。
一応、下記の方法ではできる事が確認がとれています

C#

1       //クライアント側 2 var formatter = new BinaryFormatter(); 3 4 List<string[]> sendlist = new List<string[]>(); 5 sendlist.Add(new string[] { "A", "B", "C" }); 6 7 byte[] sendBytes; 8 9 //Streamでデータをシリアライズ 10 using (var stream = new MemoryStream()) 11 { 12 formatter.Serialize(stream, sendlist); 13 sendBytes = new byte[stream.Length]; 14 sendBytes = stream.GetBuffer(); 15 } 16        17       //ソケット通信で送る*************** 18        19       //サーバー側 20       var formatter = new BinaryFormatter(); 21 22 byte[] resBytes = new byte[1024]; 23 int resSize = 0; 24 resSize = ns.Read(resBytes, 0, resBytes.Length); 25 26 //Streamでデータをデシリアライズ 27 using (MemoryStream stream = new MemoryStream()) 28 { 29 stream.Write(resBytes, 0, resSize);- 30 stream.Seek(0, SeekOrigin.Begin);- 31 List<string[]> reseveList = (List<string[]>) formatter.Deserialize(stream); 32 } 33 34

しかし、確認不足もありますが、クライアント側の端末がNET Compact Framework 3.5 でBinaryFormatterが対応していない状態です。

他に方法がないか調べていますが、下記の方法でbyte[]への変換ができたものの、サーバー側でデシリアライズが上手く行きません。

C#

1 //クライアント側 2 List<string[]> list = new List<string[]>(); 3 list.Add(new string[] { "A", "B", "C" }); 4 5 byte[] sendBytes; 6 7 using (var stream = new MemoryStream()) 8 { 9 var write = new StreamWriter(stream); 10 write.Write(list); 11 write.Flush(); 12 sendBytes = new byte[stream.Length]; 13 sendBytes = stream.GetBuffer(); 14 } 15        16       //ソケット通信で送る*************** 17 18 //サーバー側 19 byte[] resBytes = new byte[1024]; 20 int resSize = ns.Read(resBytes, 0, resBytes.Length); 21 22 // Streamでデータをデシリアライズする。 23 using (MemoryStream stream = new MemoryStream()) 24 { 25 stream.Write(resBytes, 0, resSize); 26 stream.Seek(0, SeekOrigin.Begin); 27 **ここから先がどうしていいかわからない** 28 } 29

ソケット通信とシリアライズなどはここ2日で勉強を始めており基本的な部分が抜けているかと思います
もし他に方法があれば教えてください

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

まず、

しかし、確認不足もありますが、クライアント側の端末がNET Compact Framework 3.5 でBinaryFormatterが対応していない状態です。

このこと自体は合っていますね。使えません。2009年6月と古い記事ですが:
Differences Between the .NET Compact Framework and the .NET Framework - Microsoft Docs

. the .NET Compact Framework does not support binary serialization using BinaryFormatter

とあります。何らかの代替手段が必要です。

現状のご提示のコードでbyte[]への変換ができたとありますが、実はできていません。一見byte[]で返ってきているように見えますが、ご要望のデータではないです。クライアント側のコード、以下の部分ですが、

C#

1using (var stream = new MemoryStream()) 2{ 3 var write = new StreamWriter(stream); 4 write.Write(list);

listを渡しているStreamWriter.Write(list)は、この場合はStreamWriterクラスの継承元であるTextWriterWrite(Object)が呼ばれています。
TextWriter.Write(Object)

listをそのままToString()で文字列化するとSystem.Collections.Generic.List1[System.String[]]のようになってしまうので、実際のデータ内容は欠落しています。sendBytes = stream.GetBuffer()で得られたものをダンプすれば分かるので、確認してみてください。

もし他に方法があれば教えてください

やりたいことを実現するには、例えばList<string[]> の各要素を自力で文字列化し、行データのようにしてバイナリのストリームで送るようにします。例えば以下のようなList<string[]>自体を継承したクラスを自作し、Listの各要素を1行のデータに分けます。

C#

1class MyStringListSerializer : List<string[]> 2{ 3 public override string ToString() 4 { 5 StringBuilder sb = new StringBuilder(); 6 for (int i = 0; i < this.Count; i++) 7 { 8 sb.Append(string.Join(",", this[i].ToArray())); 9 sb.Append("\n"); 10 } 11 12 return sb.ToString(); 13 } 14}

以下のコードで

C#

1MyStringListSerializer obj = new MyStringListSerializer(); 2obj.Add(new string[] { "A1", "B1", "C1" }); 3obj.Add(new string[] { "A2", "B2", "C2" }); 4Debug.Write(obj.ToString());

次のような文字列出力を得られます。この文字列をバイナリ化して送り、サーバーの受信側で文字列へ復元することで要望のデータが得られるはずです。

A1,B1,C1 A2,B2,C2

投稿2021/05/11 00:28

編集2021/05/11 00:48
dodox86

総合スコア9183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2021/05/11 00:42

サンプルコードのMyStringListSerializerクラスは実例として簡単に作ったものなので、こだわらなくて結構です。「List<string[]>などの複雑(?)なデータ構造で、BinaryFormatterが使えないなどフレームワークの制限があるなら、必要な部分は自力でしましょう。」と言うのが回答の主旨です。
RC46

2021/05/11 02:01

ありがとうございます サンプルを参考にさせていただき、単純な文字列に変換してバイナリー化してサーバーに送信し、サーバー側でsplitなどで処理して再度リスト化することで目標としていたところはできました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問