| 目次| 1234567891011121314
| 資料| 予定| 課題| 宿題|

ファイル入出力の扱い

成績処理のプログラムではプログラム中に処理するデータを直接配列として初 期設定した.また,データ整列のプログラムではランダムな配列を用意するこ とで並べ替えるべきデータを用意した.実際のプログラムではあらかじめファ イルとして用意されたデータを処理したい場合が多いので今回はファイル入出 力を扱うプログラムを紹介する.

ファイル入出力を扱う場合例外を扱う処理を追加する必要があるので まず例外とは何か,次に例外の扱いについて簡単に説明する.

例外の仕組み

     1	public class Ex12Sample1 {
     2	    public static void main(String args[]) {
     3		int test[];
     4		test = new int[5];
     5	
     6		System.out.println("test[10]に値を代入します.");
     7		test[10] = 80;
     8		System.out.println("test[10]に値を代入しました.");
     9		System.out.println("無事終了しました.");
    10	    }
    11	}
このプログラムを実行すると
test[10]に値を代入します.
java.lang.ArrayIndexOutOfBoundsException: 10
        at Ex12Sample1.main(Ex12Sample1.java:7)
のようなエラーがおきます.これは,7行目で配列要素の添字(test[10])をあ やまったからです.このようにコンパイルしたときにはわからないエラーには他に のようなエラーが考えられます.Javaでは,このようなエラーを適切に処理す るために,例外(exception)という仕組みを備えています.上の実行例でも 例外がおきていて"ArrayIndexOutOfBoundsException"という例外がプログラムの 7行目で発生したと言うことを表しています.

例外の処理(基本)

Ex12Sample1では,例外に対して特になんの処理もしていません.例外に対し て適切な処理をするコードを記述するとエラーに対応したプログラムを作成す る事ができ,この処理のことを例外処理と呼びます.Ex12Sample1を例外処理 を行うようにすると

     1	public class Ex12Sample2 {
     2	    public static void main(String args[]) {
     3		try {
     4		    
     5		    int test[];
     6		    test = new int[5];
     7	
     8		    System.out.println("test[10]に値を代入します.");
     9		    test[10] = 80;
    10		    System.out.println("test[10]に値を代入しました.");
    11		}catch(ArrayIndexOutOfBoundsException e) {
    12		    System.out.println("配列の要素を越えています.");
    13		}
    14		System.out.println("無事終了しました.");
    15	    }
    16	}
となり,その実行結果は
test[10]に値を代入します.
配列の要素を越えています.
無事終了しました.
のようになります.上のプログラムではtry, catchという二つのブロッ クを追加しています.これが例外処理の基本で以下のような構造になります.
try{
例外を検出する文;
....
}catch(例外のクラス 変数名){
例外発生時に処理する文;
....
}
このような構造を追加すると以下のような順序で例外が処理されます.
  1. tryブロック中で例外がおきると,そこで処理を中断.
  2. おこった例外の種類がcatchブロックの()内の例外と一致していれば, catchブロック内の処理を行う.
  3. catchブロックが終わったら,そのtry〜catchに続く文から処理が再開 される.

ストリームの仕組み

これから説明するファイル処理で出てくる程度の例外処理の基本は説明しまし たのでここから画面やキーボード,ファイルを使っての入出力を説明します. Javaでデータを読み書きするには,ストリーム(steram)という仕組み を使います.

ストリームとは,画面・キーボード・ファイルなどとプログラムコー ドを結びつける抽象的な概念のことです.これまでキーボードからの入力を扱 うために"KeyboardInput"というクラスを利用してきましたが,その中でも同 じように扱われています.文字列の入力を扱う部分を取り出すと以下のような プログラムになります.

     1	import java.io.*;
     2	
     3	public class Ex12Sample3 {
     4	    public static void main(String args[]) {
     5		System.out.println("文字列を入力してください.");
     6		
     7		try {
     8		    BufferedReader br =
     9			new BufferedReader
    10			    (new InputStreamReader(System.in));
    11	
    12		    String str = br.readLine();
    13		    System.out.println(str+"が入力されました.");
    14		}catch(IOException e) {
    15		    System.out.println("入出力エラーです.");
    16		}
    17	    }
    18	}
1行目
入出力を扱うためのクラスライブラリを読み込みます.
10行目
System.in(標準入出力ストリーム)からInputStreamReaderクラスのオブ ジェクトを作成して文字ストリームにします.
9行目
InputStreamReaderクラスのオブジェクトからBufferdReaderクラスのオ ブジェクトを作成してバッファリングの仕組みを持たせます.
12行目
BufferdReaderのreadLine()メソッドを使って1行読み込みます.
文字ストリームは,文字列を読み書きするために必要です.また,バッファ と呼ばれる場所を介してデータを読み書きすると,読み書きの効率がよくなり この仕組みをバッファリングといいます.

ファイルに出力する

次にファイルを使った入出力の方法を説明します.ファイルを使うとデータを 保存したり,読み込んだりしたりすることができるので,実用的なプログラム を作成できるようになります.まず,"Ex12Test1.txt"というファイルにデータ ("Hello!","GoodBye!")を書き込むプログラムを見てみます.
     1	import java.io.*;
     2	
     3	public class Ex12Sample4 {
     4	    public static void main(String args[]) {
     5		try {
     6		    PrintWriter pw =
     7			new PrintWriter
     8			   (new BufferedWriter
     9			       (new FileWriter("Ex12Test1.txt")));
    10	
    11		    pw.println("Hello!");
    12		    pw.println("GoodBye!");
    13		    System.out.println("ファイルに書き込みました.");
    14		    pw.close();
    15		    
    16		}catch(IOException e) {
    17		    System.out.println("入出力エラーです.");
    18		}
    19	    }
    20	}
9行目
"Ex12Test1.txt"というファイル名を引数としてFileWriterクラスのオ ブジェクトを作成します.
8行目
FileWriterクラスのオブジェクトからBufferdReaderクラスのオブジェ クトを作成してバッファリングの仕組みをもたせます.
BufferdReaderクラスのオブジェクトからPrintWriterクラスのオブジェ クトを作成します.
11,12行目
PrintWriterのprintln()メソッドを使ってデータを書き込む.
14行目
ファイルをクローズして処理を終わる(保存する).

ファイルから入力する

次に今書き込んだファイル"Ex12Test1.txt"という名前のファイルからデータ を読み込むプログラムを見てみます.
     1	import java.io.*;
     2	
     3	public class Ex12Sample5 {
     4	    public static void main(String args[]) {
     5		try {
     6		    BufferedReader br =
     7			new BufferedReader
     8			    (new FileReader("Ex12Test1.txt"));
     9	
    10		    String str1 = br.readLine();
    11		    String str2 = br.readLine();
    12	
    13		    System.out.println("ファイルに書き込まれている二つの文字列は");
    14		    System.out.println(str1+"です.");
    15		    System.out.println(str2+"です.");
    16	
    17		    br.close();
    18	
    19		}catch(IOException e) {
    20		    System.out.println("入出力エラーです.");
    21		}
    22	    }
    23	}
8行目
"Ex12Test1.txt"というファイル名を引数としてFileReaderクラスのオ ブジェクトを作成する.
7行目
FileReaderクラスのオブジェクトからBufferdReaderクラスのオブジェ クトを作成してバッファリングの仕組みを持たせる.
10,11行目
BufferdReaderのreadLine()メソッドを使ってデータを読み込む.
17行目
ファイルをクローズして処理を終わる.

多くのデータを入力する

このような方法を利用すると,Edit.appなどで作成したファイルから大量のデー タを読み出すこともできます.まず,次のような"seiseki.txt"ファイル(空行や英字など含まないこと)を用意します.
93
48
73
88
34
46
62
80
これは,8人の学生のテストの点数を入力したデータです.これを "seiseki.txt"というファイル名を指定して読み込み成績処理を行うプログラ ムは次のようになります.
     1	import java.io.*;
     2	
     3	public class Ex12Sample6 {
     4	    public static void main(String args[]) {
     5		if( args.length !=1) {
     6		    System.out.println("ファイル名を正しく指定してください.");
     7		    System.exit(0);
     8		}
     9		try {
    10		    BufferedReader br =
    11			new BufferedReader
    12			    (new FileReader(args[0]));
    13	
    14		    int test[] = new int[100];
    15		    int num = 0;
    16		    String str;
    17	
    18		    while((str = br.readLine())!= null){ //EOFの検出
    19			test[num] = Integer.parseInt(str); //空行,アルファベット?
    20			num++;
    21		    }
    22	
    23		    int max = test[0];
    24		    int min = test[0];
    25		    for(int i=0; i<num; i++){
    26			if( max<test[i]) {
    27			    max = test[i];
    28			}
    29			if( min > test[i]) {
    30			    min = test[i];
    31			}
    32			System.out.println(test[i]);
    33		    }
    34	
    35		    System.out.println("最高点は"+max+"です.");
    36		    System.out.println("最低点は"+min+"です.");
    37	
    38		    br.close();
    39	
    40		}catch(IOException e) {
    41		    System.out.println("入出力エラーです.");
    42		}
    43	    }
    44	}
5〜8行目
入力方法が正しくない(引数の数が違う)場合
10〜12行目
1番目の引数を表す文字列変数args[0]を参照し,そのファイル名のファ イルからストリームを作成します.
18〜21行目
ファイルを最後まで読み込みます.
25〜33行目
点数を表示しながら,最高点・最低点を調べます.
実行例は以下のようになります.
[onisi@mm10a1 ~/Java] java Ex12Sample6 seiseki.txt
93
48
73
88
34
46
62
80
最高点は93です.
最低点は34です.

課題

  1. 紹介したプログラムを入力し動作の確認を行いなさい.
  2. コマンドライン引数で指定されたファイルの中身を行番号をつけて表示するプ ログラムを作成しなさい.

| 目次| 1234567891011121314
| 資料| 予定| 課題| 宿題|