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

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

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

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

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

Q&A

解決済

2回答

5101閲覧

C#でBinaryformatterを使ってクラスを繰り返しSerializeした後、ファイルをDeserializeしたい

Inary

総合スコア13

C#

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

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

0グッド

0クリップ

投稿2018/11/20 01:51

前提・実現したいこと

クラスをSerializeした後、そのファイルからクラスを配列で格納したいのですが、うまくいかず。。。
大変恐縮ですが、ご教授いただければ幸いです。
よろしくお願いします。

該当のソースコード

C#

1//連続して書くクラス 2[Serializable] 3public class data 4{ 5 uint A; 6 uint B; 7 string C; 8 List<double> D; 9 List<byte> E; 10} 11

c#

1//write関数 2public void Write(data X, string filepath) 3{ 4 Binaryfommatter bf = new Binaryformatter(); 5 FileStream fs = new FileStream(filepath,FileMode.Open); 6 bf.Serialize(fs,data); 7}

C#

1//Read関数 2public data read(string filepath) 3{ 4 Binaryfommatter bf = new Binaryformatter(); 5 FileStream fs = new FileStream(filepath,FileMode.Open); 6 data dt = (dt)bf.Deserialize(fs); 7} 8 9

試したこと

クラス一発だけSerializeしたときはDesrializeできることは確認できているのですが、
連発してSerializeしたときには処理がエクセプションなく関数が終了してしまう。

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

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

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

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

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

kikukiku

2018/11/20 01:54

どのように連発してSerializeしているのか?Exceptionなく処理が終了する最低限のソースの開示が一番の早道かと思います。
YAmaGNZ

2018/11/20 02:08 編集

ソースを提示するのであれば、コンパイルの通るソースを提示すべきかと思います。 現状のソースですと、コンパイルを通るように修正しても動作しません。
guest

回答2

0

ベストアンサー

次のように試してみてください。

C#

1using System; 2using System.Collections.Generic; 3using System.IO; 4using System.Linq; 5using System.Runtime.Serialization.Formatters.Binary; 6 7namespace ConsoleApp1 8{ 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 string desktopDir = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); 14 string fileName = Path.Combine(desktopDir, "data.bin"); 15 using (var stream = File.Create(fileName)) 16 { 17 var bf = new BinaryFormatter(); 18 bf.Serialize(stream, new Person("Alice", 13)); 19 bf.Serialize(stream, new Person("Bob", 14)); 20 bf.Serialize(stream, new Person("Charley", 15)); 21 } 22 var People = Deserialize(fileName).ToArray(); 23 foreach (var person in People) 24 { 25 Console.WriteLine(person); 26 } 27 Console.ReadKey(); 28 } 29 30 static IEnumerable<Person> Deserialize(string fileName) 31 { 32 using (var stream = File.OpenRead(fileName)) 33 { 34 var bf = new BinaryFormatter(); 35 while (stream.Position < stream.Length) 36 { 37 yield return (Person)bf.Deserialize(stream); 38 } 39 } 40 } 41 } 42 43 [Serializable] 44 class Person 45 { 46 public Person(string name, int age) 47 { 48 (Name, Age) = (name, age); 49 } 50 public string Name { get; set; } 51 public int Age { get; set; } 52 public override string ToString() 53 { 54 return $"{Name}({Age})"; 55 } 56 } 57}

投稿2018/11/20 03:29

Zuishin

総合スコア28660

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

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

Zuishin

2018/11/20 03:41

(Name, Age) = (name, age); ここでエラーが出る場合にはつぎのように書き換えてください。 Name = name; Age = age;
Zuishin

2018/11/20 03:42

return $"{Name}({Age})"; ここでエラーが出る場合には次のように書き換えてください。 return string.Format("{0}({1})", Name, Age);
hihijiji

2018/11/20 03:52

ファイルポインタを使わなくてもFileStreamが場所を覚えてるんですね。
Zuishin

2018/11/20 03:55

そうですね。 開いている間は覚えています。 質問を見たところ、データを一つ読むたびにファイルを閉じているのではないかと思いました。
hihijiji

2018/11/20 04:01

と言うかBinaryFormatterは与えられたストリームを最後まで読んじゃうと思い込んでました。 勉強になりました。
Inary

2018/11/20 23:31

無事クラスごとdeserialize出来ました。とても親切にご教授いただきありがとうございました。
guest

0

ひょっとして、一つのファイルに追記でシリアライズ出力した後、それらをまとめて取り出したいってことでしょうか?
BinaryFormatterはそうゆう風に作られてませんので、それは簡単には出来ません。
実現するには別途ファイルポインタなどをの仕組みを自前で用意する必要があります。
とても面倒でバグの温床になり易いので、普通はしません。
初めから配列でシリアライズするかRDBMSなどを使ったほうが簡単で確実です。

投稿2018/11/20 02:32

hihijiji

総合スコア4150

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

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

Inary

2018/11/20 03:10

回答ありがとうございます。 質問が下手で申し訳ありません。 仰るとおりで一つのファイルに追記でシリアライズ出力した後、まとめて配列で取り出したいということです。 BinaryFormatterが使用できないということは理解できました。 何万ものデータをバッファにためておくのはメモリが足りないので配列に格納することができない状況なので。。 別の方法というとテキスト出力もしくはRDBMSやNoSQLのようなデータベースによる出力を行う方が良いということですね。 大変ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問