== ファイル入力 ==
ファイル入出力のために、
つぎの4つをスーパークラスとする数十個のクラスが用意されています。
. !InputStream バイト入力
. !OutputStream バイト出力
. Reader テキスト入力
. Writer テキスト出力
なおこの4つは抽象クラスのため、直接利用することはできません。
----
=== 概要 ===
テキスト形式のファイルからの入力には Readerクラスのサブクラスである !BufferedReader クラスを利用します。
!BufferedReader クラスの readLineメソッドを使うことで1行ずつ読み取ることができます。
利用する機能は次の3つです。
{{{#!java
BufferedReader b;
String s;
b = new BufferedReader( ... );
s = b.readLine();
b.close();
}}}
. 4行目で、!BufferedReaderクラスのインスタンスを作ります。
. 5行目で、このインスタンスを使ってreadLineメソッドを使って1行分読み取り、結果を文字列sに代入しています。
. 6行目で、ファイルを閉じています。
ファイルを使い終わったときには、ファイルを閉じる処理が必要です。<
>
ファイルの使い始めのopenは必要ありません。インスタンスを作ればよい。
----
=== インスタンスの作成 ===
!BufferedReaderインスタンスを作成するときには、
コンストラクタの引数として!FileReaderのインスタンスを与える必要があります。
!FileReaderコンストラクタの引数にはファイル名を与えます。
{{{
FileReader f;
f = new FileReader( "filename" );
b = new BufferedReader( f );
}}}
インスタンスfはここでしか用いないので、次のように記述することもある。
{{{
b = new BufferedReader( new FileReader( "filename" ) );
}}}
ファイル名や1文字ごとの情報は!FileReaderインスタンスの状態として保持され、
行単位の情報は!BufferedReaderインスタンスの状態として保持されると考えればよい。
. {{attachment:filereader1.png}}
処理は!BufferedReaderインスタンスへのメソッドを通して行います。
----
=== 各行の入力 ===
readLineメソッドはファイルの終わりに達したときは null を返します。<
>
ファイルを1行づつ読んで終わりまで処理するには、5行目を次のように修正します。
{{{
while( true )
{
s = b.readLine();
if(s == null)
break;
// 各行での必要な処理はここに書く
}
}}}
これと同じ内容を、次のように書くこともできます。
{{{
while( (s = b.readLine() ) != null)
{
// 各行での必要な処理はここに書く
}
}}}
----
ここまでをまとめると次のようになります。
{{{#!java
FileReader f;
BufferedReader b;
String s;
f = new FileReader( "filename" );
b = new BufferedReader( f );
while( (s = b.readLine()) != null)
{
// 各行での必要な処理はここに書く
}
b.close();
}}}
----
=== 例外処理 ===
プログラム実行中になんらかの例外が起こることがあります。
例外が起こったときにプログラムの実行を中断するのではなく、なんらかの処理を行うよう記述できます。
. {{attachment:reigai1.png}}
例外処理の記述には try,cahtch 構文を用います。
. {{attachment:reigai2.png}}
* 1番目の(try)ブロックに通常の処理(図の青の部分)を記述します。
* 例外には受け取る例外の型と変数を記述します。
* 後ろの(catch)ブロックには例外が起こったときの処理(図の赤の部分)を記述します。
ブロックは
. { で始まり
. 文を必要なだけ書き
. } で終わりました。
通常は次のように記述します。
catchの箇所のインデントの仕方が、他の場合と違います。
{{{
try
{
...
} catch(...) {
...
}
}}}
----
=== ファイル入力時の例外処理 ===
ファイル入力時には例外が発生する可能性があるので、必ずtry,catchを書きます。
ファイルを開く(インスタンスを作る)ところから、ファイルを閉じるところまでの範囲をtryのブロックにし、
その後ろにcatchを加えます。
ファイル入力のときの例外は Exception型とし変数名をつけます。
ファイル sample.txt の内容を表示するプログラムは次のように書けます。
{{{#!java
public class ReadSample
{
public static void main(String[] args)
{
try
{
FileReader f;
BufferedReader b;
String s;
f = new FileReader( "sample.txt" );
b = new BufferedReader( f );
while( (s = b.readLine()) != null)
{
System.out.println( s );
}
b.close();
} catch(Exception e) {
System.out.println( e );
}
}
}
}}}
----
=== パッケージを利用する ===
Javaであらかじめ用意されているクラスはパッケージに分けて管理されています。
上に示したプログラムをコンパイルしようとすると、!FileReaderや!BufferedReaderが分かりません、というエラーが出ます。
利用するクラスがどのパッケージに含まれているかを示さなければなりません。
. !FileReaderと!BufferedReaderはjava.ioパッケージに含まれています。
書き方1 '''クラス名をフルネームで書く'''
. クラスのフルネームとはパッケージ名とクラス名をピリオドではさんでつないだものです。
. プログラム中で使われている箇所をフルネームに修正します。
. 例
. java.io.!FileReader
. java.io.!BufferedReader
書き方2 '''import文でフルネームを書く'''
. プログラムの先頭にimport文を追加し、利用するクラス名をフルネームで書く。
. これによりプログラム中ではフルネームで書かなくても、省略してクラス名だけで使える。
. 例
. import java.io.!FileReader;
. import java.io.!BufferedReader;
書き方3 '''import文でパッケージを指定する'''
. プログラムの先頭にimport文を追加し、利用するパッケージを書く。
. 同じパッケージ内の複数のクラスを利用するときは、パッケージの後ろに * をつけて示すことができる。
. 例
. import java.io.*;