FC2ブログ
ヽ|∵|ゝ(Fantom) の 開発blog? ホーム » Java »【Java】【Android】テキストファイルを読み込む

【Java】【Android】テキストファイルを読み込む  


 Java のファイル読み込みはわかりずらいね。Java の欠点としてクラスが多すぎ(笑)。抽象クラスも含むから初めは何を使ったらいいかわからない。

※Android の各デバイスなどで使えるように、ライブラリ化したものをまとめたものは → こちら

 おおまかには、InputStream, FileInputStream, InputStreamReader, FileReader, BufferedReader などを使う。他にも色々あるけど、とりあえずこのあたりを理解すれば使える。違いを理解するために、わざと色々な書き方をしてみる。仕様としては、前回の StreamTokenizer とほとんど同じ。適当にファイルを読み込んで表示するだけだ。

public void readFileTest(String fileName) {
//ファイル名から File オブジェクトを生成
File file = new File(fileName);

//raw バイトのストリームをオープン
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
return;
}

//バイトストリームから文字ストリームへ変換
InputStreamReader isr = null;
try {
isr = new InputStreamReader(fis, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
if (fis != null) {
try {
fis.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
return;
}

//バッファリングしながら読み込むReader
try {
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) { //1行ごとに読み込む
System.out.println(line);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}

//メインではファイル指定のみ
String fileName = "C:/test/sample.txt";
readFileTest(fileName);

 長いね・・・。わざと例外処理を細かく入れてるけど、1つ1つやっていくと本当に長い。要するに入力ストリームを開いて、文字エンコードストリームを中継、それを1文字ずつ読み込むのは効率悪いので、バッファリングしながら1行ごとに一気に表示、って感じ。FileInputStream はそのまま InputStream に置き換えられる。

 少し長いので例外処理を手抜きしてまとめてみる。メインは同じ。

public void readFileTest(String fileName) {
try {
FileInputStream fis = new FileInputStream(fileName); //raw バイトのストリームをオープン
InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); //バイトストリームから文字ストリームへ変換
BufferedReader br = new BufferedReader(isr); //バッファリングしながら読み込むReader
String line;
while ((line = br.readLine()) != null) { //1行ごとに読み込む
System.out.println(line);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}

 随分短くなって機能がわかりやすい。FileInputStreamFile オブジェクトにしなくても直接ファイル名でもいいので、省略。
 あとは開いた FileInputStreamInputStreamReader も途中で変えることはないので、これも無理矢理まとめてみる。

public void readFileTest(String fileName) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), "UTF-8"));
String line;
while ((line = br.readLine()) != null) { //1行ごとに読み込む
System.out.println(line);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}

 もう1つ、FileReader という文字ストリーム用のクラスがあって、これはデフォルトのエンコードで良い場合や byte バッファのサイズが適切に設定されているときに、InputStreamReaderFileInputStream をまとめたようなものになってる。エンコードは UTF-8 と決まっていて、バッファは BufferedReader にお任せなら、上記のコードをショートカット的に使うこともできる。

public void readFileTest(String fileName) {
try {
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line;
while ((line = br.readLine()) != null) { //1行ごとに読み込む
System.out.println(line);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}

 はじめからすると、半分以下のコードになったね(笑)。自分で使う分にはこれでも良いかも。でもこれは例外処理が分岐されてないので、汎用的には向かないかもね。まぁ、実際には一番多いのが「ファイルが見つからない(FileNotFoundException)」であって、IOException はローカルならあまり出ない気もするが・・・。ネット経由なら別だけどね。

 ストリームのクローズ状態が心配なら、finally ブロックにするのもいいかもね。

public void readFileTest(String fileName) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(fileName));
String line;
while ((line = br.readLine()) != null) { //1行ごとに読み込む
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}

 今度はちょっと長くなったが、close() は既に閉じられているときは何もしないので、ここまでやっておけば、とりあえずどこでエラー出ても心配はないかもしれない。

 あとは、例外処理を throws を使ってメインに投げてしまう手もあるね。ただし、メインでは例外処理が必要になるわけだが・・・。

public void readFileTest(String fileName) throws IOException, FileNotFoundException {
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}

//メインでは例外処理が必要
String fileName = "C:/test/sample.txt";
try {
readFileTest(fileName);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

 メソッドはわずか数行(笑)。書き方は千差万別だね。用途に応じて変えるのも良いかも。ちなみに1行ごとではなく、1文字ずつ読み込みたい場合は、while の部分を、

int ch;
while ((ch = br.read()) != -1) { //1文字ずつ読み込む
System.out.print((char)ch);
}

に置き換えればいい、Android の assets から読み込んで使いたい場合は前回と同じように、AssetManager からストリームをオープンして、一番最初の例の InputStreamReader につっこめばそのまま使える。基本が分かれば同じようなもんだね。これでシナリオ読み込みなどにも使えるね。

(関連記事)
【Android】【Applet】【Java】テキストファイルの読み込み・保存 まとめ
【Java】ストリームからテキストファイルを読み込む(ストリームから読み込み、テキストエンコードして返す)
【Android】res/raw リソースフォルダからテキストファイルを読み込む
【Android】assets フォルダからテキストファイルを読み込む
【Android】内部ストレージからテキストファイルを読み込む
【Android】内部ストレージにテキストファイルを保存する
【Android】SDカードからテキストファイルを読み込む
【Android】SDカードにテキストファイルを保存する
【Android】エラーをSDカードに書き出す
【Java】ローカルシステム(Windows 等)から、テキストファイルを読み込む
【Applet】URL経由でWebサーバ上のテキストファイルを読み込む
【Applet】jar 内リソースからテキストファイルを読み込む
【Java】JSON を PHP から送信して、Java で受信する


関連記事
スポンサーサイト



category: Java

thread: プログラミング

janre: コンピュータ

tag: テキストファイル読み込み 
tb: 0   cm: --


トラックバック

トラックバックURL
→http://fantom1x.blog130.fc2.com/tb.php/96-1a0da45d
この記事にトラックバックする(FC2ブログユーザー)

プロフィール

Social

検索フォーム

全記事一覧

カテゴリ

ユーザータグ

最新記事

リンク

PR