こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

javaのプログラムの質問です。

10件まで登録できる簡易メモリストを作成して下さい
実行例: > java MemoList
> コマンドを入力して下さい:list
1:俺達がガンダムだ!
2:ザクとは違うのだよザクとは!
3:当たらなければどうという事はない!

コマンド
list
メモリストを1~の番号と共に表示
add
メモを追加
del
メモ番号を入力して削除
upd
メモ番号を入力して上書き
save
ファイルに保存
h
コマンド一覧を表示
q
終了

注意点
・プログラム起動時にファイルからメモリストを読み込んで下さい
・保存するファイルは任意の固定ファイルで構いません
・メモは1~の連番で10件まで登録可能として下さい
・終了のコマンドが入力されるまで何度でもコマンド入力可能として下さい
・JavaDoc/プログラムコメントはしっかり記述して下さい
・エラー発生時は適切なメッセージを標準出力に出力して下さい

という問題なのですが、以下のソースでとりあえずは動くのですが。

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;

class MemoList{
/**
* メインメソッド
**/
public static void main(String[] args) throws IOException {
// Fileクラスのインスタンス化
File file1 = new File("C:\\WORK\\Memo.txt");

// FileReaderクラスのインスタンス化
FileReader filereader = new FileReader(file1);

// FileWriterクラスのインスタンス化
FileWriter filewriter = new FileWriter(file1);

// BufferedReader&InputStreamReaderクラスのインスタンス化
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

ArrayList <String> arraylist = new ArrayList<String>();
int num = 1;

// while文ループを行う
while(true){
System.out.println("> コマンドを入力して下さい:");
String str1 = br.readLine();

if("list".equals(str1)){
   for(int i=0; i < arraylist.size(); i++){
     System.out.println(i + 1 + ":" + arraylist.get(i));
   }
} else if("add".equals(str1)){

System.out.println("> メモを入力して下さい。");

if(arraylist.size() == 10){
   System.out.println("> 10件登録されています。追加する場合は削除して下さい。");

   delete(br,arraylist);

}else{
String str2 = br.readLine();

arraylist.add(str2);
}
}else if("del".equals(str1)){

delete(br,arraylist);

}else if("upd".equals(str1)){

System.out.println("> 上書きするメモ番号を入力して下さい。");

try{

  String str4 = br.readLine();

  int num2 = Integer.parseInt(str4);

  System.out.println("> 上書きする内容を入力して下さい。");

   String str5 = br.readLine();

  arraylist.set(num2 - 1,str5);

}catch(NumberFormatException e){

System.out.println("正しい番号を入力して下さい");

}catch(IndexOutOfBoundsException e){

System.out.println("正しい番号が入力されていないので上書き出来ません");
}

(1)}else if("save".equals(str1)){

try{

for(int j=0; j < arraylist.size(); j++){

filewriter.write(arraylist.get(j) + "\r\n");

}
System.out.println(">ファイルに保存しました。");

filewriter.close();

}catch(IOException e){

(2) System.out.println("ファイルに保存出来ません");
(3) }

}else if("h".equals(str1)){

System.out.println("list:メモリストを1~の番号と共に表示");
System.out.println("add:メモを追加");
System.out.println("del:メモ番号を入力して削除");
System.out.println("upd:メモ番号を入力して上書き");
System.out.println("save:ファイルに保存");

}else if("q".equals(str1)){
   System.out.println("> Terminated");
   break;
}
}
}

// deleteメソッド
public static void delete(BufferedReader br,ArrayList<String> arraylist) throws IOException {
try{

  System.out.println("削除するメモ番号を入力して下さい");

  String str3 = br.readLine();

  int num3 = Integer.parseInt(str3);

  arraylist.remove(num3 - 1);

}catch(IndexOutOfBoundsException e){
    System.out.println("正しい番号を入力して下さい");

}catch(NumberFormatException e){
   System.out.println("正しい番号以外は受け付けません");
}
}
}

読みにくいのはご容赦ください。

(1)と(3)の間の処理なのですが、現在のソースで実行した場合、適当に「add」でメモを書き、最初に「save」コマンドを入力するとちゃんとWORKフォルダ内に作成した「Memo.txt」に保存されます。しかし、2回目以降、コマンドを入力して処理を行い、saveコマンド入力すると、例外処理となり(2)が表示され、以降はどのコマンド処理をしても(2)が表示され続けるという具合になってしまいます。どなたか教えていただけないでしょうか?よろしくお願い致します。
通報する

投稿日時 - 2014-11-12 19:22:52

QNo.8822794

すぐに回答ほしいです

質問者が選んだベストアンサー

Javaでは(Javaに限った話ではないけど)ストリームの読み書きは可能な限り局所的にする方がいい。少なくとも他の何かを待っている(今回の話ではコマンド入力待ち)状態でファイルストリームを開きっぱなしにするというのは本当にその必要がある場合にのみ行うべきだ。

具体的に言うと、mainの冒頭でFileWriterがあるのはおかしいよね。今起動したんだから今は読みたいだけのはず。書くのはsaveの指令が出てからだ。

つまり、
起動時:FileReaderをnewして読んでclose。
saveと打たれた時:FileWriterをnewして書いてclose。
とすべきだ。

そこらへんを見直すと今回困っている原因も分かるはず。

投稿日時 - 2014-11-13 01:46:16

ANo.2

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.1

2回目の save で例外が発生するのは、1回目の書き込みの後で FileWriter オブジェクトを close してしまっているからです。
close したら、以後そのオブジェクトに対しては何の操作もできません。

投稿日時 - 2014-11-12 20:52:27

あなたにオススメの質問