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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

3402閲覧

ファイルに書き込んだオブジェクトを全て読み込みたいが、先頭にある1つ目しか読み込むことができない

fgfnabwym

総合スコア78

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2016/11/21 11:26

シリアライズとデシリアライズをし、ファイルにオブジェクトの読み書きをしたいです。追加の書き込みはできるのですが、読み込みが上手くいきません。
何度読み込んでも、ファイルに一番初めに書き込んだオブジェクトしか得ることが出来ません。

ファイルに書き込んだすべてのオブジェクトを読み込みたいです。

main関数でループを回すという方法を考え、RandomAccessFileを使いファイルポインタの動かしてというやり方をしていたのですが上手くいきませんでした。
1行ずつ読み込むという方法もあったのですが、オブジェクトでは型が違いますとエラーになってしまいます。

もしうまい方法を知っている方がいればぜひ教えてください。
よろしくお願い致します。

Member.javaファイル

Java

1package hello; 2 3import java.io.Serializable; 4 5public class Member implements Serializable { 6 7 public String name; // 氏名 8 public int age; // 年齢 9}

SerializableSampleTest.javaファイル

Java

1package hello; 2import java.io.FileInputStream; 3 4import java.io.FileOutputStream; 5import java.io.IOException; 6import java.io.ObjectInputStream; 7import java.io.ObjectOutputStream; 8import java.util.ArrayList; 9import java.util.List; 10 11 12public class SerializableSampleTest { 13 public static void main(String[] args) { 14 SerializableSampleTest sst1 = new SerializableSampleTest(); 15 SerializableSampleTest sst2 = new SerializableSampleTest(); 16 17 18 // 一人目 19 Member mb1 = new Member(); 20 mb1.name = "sakura"; 21 mb1.age = 20; 22 23 List Akumi = new ArrayList(); 24 Akumi.add(mb1.name); 25 Akumi.add(mb1.age); 26 27 sst1.write(Akumi); 28 29 // 二人目 30 Member mb2 = new Member(); 31 mb2.name = "yuri"; 32 mb2.age = 19; 33 34 List Bkumi = new ArrayList(); 35 Bkumi.add(mb2.name); 36 Bkumi.add(mb2.age); 37 38 sst2.write(Bkumi); 39 40 41 System.out.println(sst1.read()); 42 System.out.println(sst2.read()); 43 44 45 46 } 47 48 public void write(java.util.List<Member> Mem) { 49 // シリアライズ 50 try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("member", true))) { 51 oos.writeObject(Mem); 52 System.out.println("シリアライズ完了"); 53 oos.close(); 54 55 } catch (IOException e) { 56 System.out.println("error"); 57 } 58 } 59 60 public java.util.List<Member> read(){ 61 java.util.List<Member> Mem = null; 62 63 // デシリアライズ 64 try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("member"))) { 65 Mem = (List<Member>) ois.readObject(); 66 System.out.println("デシリアライズ完了"); 67 ois.close(); 68 } catch (IOException | ClassNotFoundException e) { 69 System.out.println("error"); 70 } 71 return Mem; 72 } 73 74 }

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

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

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

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

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

guest

回答2

0

ベストアンサー

A-pZさんの回答に同意です。自分は以下の点について若干コメントします。

ファイルに書き込んだすべてのオブジェクトを読み込みたいです。

もし現在の書き込み方式(複数のObjectOutputStreamを用いてファイルへ追記する方法)のままとするなら、書き込みと同じ順番・回数だけ個別のObjectInputStreamを用い、かつ直前のオブジェクト読み込み完了時のInputStreamのリード位置を調べ次のObjectInputStreamを用いたリードの際にInputStreamに対してシークしておかなければなりません。質問者さんもこの点を意識しておられたと思いますが、try-resource文を使う関係で以下のようにされたのではないでしょうか。

  1. RandomAccessFileを生成
  2. RandomAccessFileをwrapするInputStreamを生成
  3. InputStreamからObjectInputStreamを生成
  4. RandomAccessFileをシーク
  5. readObject

こうすると5.で例外が発生すると思います。原因はObjectInputStreamのコンストラクター内でInputStreamが先読みされることにあるようです。とりあえず回避は4のシーク処理を3より前に行うことですが、ただObjectInputStreamが先読みを用いている事実があるので個人的に気持ち悪さが残ります(readObject完了時点で本来必要なデータの終端を超えて先読みすることがないのかという点で)。もし可能なら単一のObjectOutputStreamで全てのオブジェクトを一気に書き込む(読み込みも同様)方が安心な実装だと思いました。

投稿2016/11/21 21:50

KSwordOfHaste

総合スコア18394

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

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

fgfnabwym

2016/11/23 11:27

ありがとうございます。教えたいただいた方法で書き直してみます
guest

0

少し気になるコードがあります。

java

1public void write(java.util.List<Member> Mem) { 2 3}

と、writeメソッドは List<Member>を受け取るメソッドですが、このメソッドを使っているmainメソッドでは

java

1List Akumi = new ArrayList(); 2Akumi.add(mb1.name); 3Akumi.add(mb1.age); 4 5sst1.write(Akumi);

と、バラバラに足しこんでいますが、Akumi.add(mb1) ではないでしょうか。

あと、例外をキャッチしている箇所でエラーメッセージを出していますが、できれば、

} catch (IOException | ClassNotFoundException e) { System.out.println("error"); e.printStackTrace(); }

と、例外が発生した内容を出力するようにした方が良いでしょう。

投稿2016/11/21 13:03

A-pZ

総合スコア12011

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

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

fgfnabwym

2016/11/23 11:26

ありがとうございます。修正します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問