初心者の方がJavaでファイルを読み込むためのクラスとして一番に思い浮かぶものは、恐らく”FileReaderクラス”ではないでしょうか?
確かに”FileReaderクラス”でも間違いではありません。
しかし”もっと楽に”読み込めるクラスがあるのも事実です。
今回はそんな”もっと楽に”にスポットを充て、”FileReaderクラス”と”BufferedReaderクラス”について解説してみたいと思います。
それぞれの特徴
ファイルを読み込むためのクラスと言っても、動きが違えば使うシーンも違ってきます。
シーンを間違って使っても特に問題があるわけではないのですが、やはりここはスマートな方法を覚えておくことがベストプラクティスではないでしょうか。
ということでこの項目では、”FileReaderクラス”と”BufferedReaderクラス”、それぞれの特徴について解説してみたいと思います。
FileReaderクラス
FileReaderクラスはテキストファイルを読み込むためのAPIです。
テキストファイルの内容を元にした処理などを行うために使います。
FileReaderクラスではファイルのデータストリームは文字となります。
BufferedReaderクラス
BufferedReaderクラスもFileReaderクラスと同じく、テキストファイルを読み込むためのAPIです。
同じくと書きましたが、厳密には上位互換クラスと言った方が良いでしょう。
上位互換と言える一番の理由はメソッドの違いにあります。
例えばFileReaderクラスには”read”というメソッドはあっても”readLine”というメソッドはありません。
“BufferedReader”の方が良い理由
勘の良い方はもうお気づきだと思いますが、テキストファイルを読み込むのであれば”BufferedReaderクラス”を使うべきです。
理由は、”FileReaderクラス”は1文字ずつ読み込みを行う仕様のため、文字数の多いテキストなどを読み込ませると効率が落ちてしまいます。
それに対し”BufferedReaderクラス”は一定の量をメモリに溜めこみ、ある程度の量になったら自動でOSに対し読み込み命令を出してくれるので効率よく処理できます。
この処理をバッファリングと呼びます。
readLineを使って読み込む方法
ここまでは”FileReaderクラス”と”BufferedReaderクラス”の違いを一通り説明しましたので、この項目では実際にコードを使った説明をしてみたいと思います。
早速ですが、次のコードを見てください。
import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; public class BufferedReaderSample { public static void main(String[] args) { try { File file = new File("c:\\Sample\\sample.log"); if (!file.exists()) { System.out.print("ファイルが存在しません"); return; } FileReader fileReader = new FileReader(file); BufferedReader bufferedReader = new BufferedReader(fileReader); String data; while ((data = bufferedReader.readLine()) != null) { System.out.println(data); } bufferedReader.close(); } catch (IOException e) { e.printStackTrace(); } } }
実行結果
ファイルを読み込みました。 読み込み成功!
上のコードでは、BufferedReaderクラスに用意されている”readLineメソッド”を使いファイルを読み込ませ、内容を出力しています。
流れとしては、まず最初に”File”オブジェクトを作成し、引数にファイルパスを割り当てます。
次に、FileNotFoundExceptionを回避する為に、Fileクラスに用意されている”exists”メソッドを使ってファイルの有無をチェックします。
“exists”メソッドは戻り値がBoolean型となっているため、ファイルが存在すればtrueを返します。
尚、この行のif文では存在をチェックするだけの作業のため、ファイルが存在しない場合のみ処理を記述します。
続いて、Fileクラスのコンストラクタを作成し、引数にFileオブジェクトを指定します。
最後に”BufferedReader”のコンストラクタを作成し、引数に先ほどのFileクラスのコンストラクタを指定します。
こうすることによってバッファリングをFileクラスのコンストラクタ全体にかけることが出来ます。
“readLine”メソッドは1行ずつ読み込みを行い読み込み完了時点で”null”を返すため、while文を使いファイル全体を行がなくなるまでループ処理させます。
読み込み処理が完了したらリソースを開放させるために、”close”メソッドで必ずファイルを閉じてください。
今回は「sample.log」の中身に”ファイルを読み込みました。\n読み込み成功!”とだけ記述しているサンプルファイルを用意して解説していますので、実行結果でも同じ文章が出力されていることが確認できます。
文字コードを変換して読み込む
文字コードを変換したい場合にはBufferedReaderクラスで読み込む前の段階で一つ処理を加えることで可能になります。
次のコードを見てください。
import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; public class BufferedReaderSample { public static void main(String[] args) { try { File file = new File("c:\\Sample\\sample.log"); if (!file.exists()) { System.out.print("ファイルが存在しません"); return; } FileInputStream input = new FileInputStream(file); InputStreamReader stream = new InputStreamReader(input,"UTF-8"); BufferedReader bufferedReader = new BufferedReader(stream); String data; while ((data = bufferedReader.readLine()) != null) { byte[] b = data.getBytes(); data = new String(b, "Shift-JIS"); String[] col = data.split(",", -1); for ( int i=0; i<col.length; i++){ System.out.println(col[i]); } } bufferedReader.close(); } catch (IOException e) { e.printStackTrace(); } } }
上のコードでは、InputStreamReader及びFileInputStreamクラスを中継してBufferedReaderクラスで使用することで、文字コードを指定して読み込んでいます。
まとめ
いかがでしたか?
今回は”BufferedReader”の違いと利用方法について解説してみました。
アプリ開発ではファイルを扱うことが非常に多くなりますので、キチンとした理解を深めておくことをお勧めします。