Java

[java.io] Java文字列入力のまとめ (InputStream, Reader, Scanner)

More than 1 year has passed since last update.

最近、授業で Java を書くことになりました。
File, InputStream, FileReader, Scanner の関係がよくわからなかったのでまとめます。

この記事では、Java SE 1.8 を前提としています。
ただし、この記事は java.nio ではなく、古い java.io についてのまとめです。

コード中には、例外処理が書かれていませんが、ファイルを開くときには FileNotFoundException を、ファイルを読み書きするときには IOException を受け取れるようにしておく(または、さらに上のメソッドに投げる)必要があります。

ページの下の方にまとめの図があります。

java.io のリファレンス

https://docs.oracle.com/javase/jp/8/docs/api/java/io/package-summary.html

File, FileDescriptor

  • java.io.File
    パスの抽象表現(パスの単なる表現で開いたファイルを保持したりはしていない)
  File file = new File("file.txt"); // ファイル名から作れる
  • java.io.FileDescriptor: 開いたファイルを表す。ハンドルとして機能。

InputStream

バイトを読み込むためのクラス

  • java.io.InputStream 抽象クラス
    • java.io.FileInputStream: ファイルから InputStream を構築するためのクラス
    • java.io.FilterInputStream: InputStream を保持するためのクラス
      • java.io.BufferedInputStream: InputStream をバッファして自身も InputStream として見せる。
// System.in は InputStream のインスタンス
InputStream sytemin = System.in;

// ファイルからストリームを作る
InputStream fileStream = new FileInputStream("file.txt");
// ストリームをバッファする
InputStream bufferedStream = new BufferedInputStream(fileStream); 

bufferedStream.close();

Reader

InputStream'Reader' のように名前の最後に 'Reader' とついているクラスは、文字列ストリームを読み込むためのクラスです。

  • java.io.Reader 抽象クラス
    • java.io.InputStreamReader: InputStream => Reader への橋渡し。文字セットを指定できる
    • java.io.FileReader: 簡易クラス (File, FileDescriptor, fileName で Reader 構築。文字エンコーディングは指定できない。)
    • java.io.BufferedReader: Reader クラスをバッファ
// ファイルからバイトストリームを作る
InputStream fileStream1 = new FileInputStream("file1.txt");
// バイトストリームから文字列ストリームを作る
Reader reader1 = new InputStreamReader(fileStream1);

// ファイルからバイトストリームを作る
InputStream fileStream2 = new FileInputStream("file2.txt");
// 文字列ストリームを作る。文字列エンコードの指定
Reader reader2 = new InputStreamReader(fileStream2, "utf-8");

// 簡易クラスを使って、ファイルから Reader を直接作る
Reader reader3 = new FileReader("file3.txt");

// リーダーをバッファする
BufferedReader bufferedReader3 = new BufferedReader(reader3);
// BufferedReader には、テキスト行を読み込む readLine() がある
String line = bufferedReader3.readLine();

reader1.close();
reader2.close();
bufferedReader3.close();

java.util.Scanner

テキストから int, long, boolean などのプリミティブ型や文字列を取得するスキャナー。
File クラスや、InputStream クラスから構築できる。文字列エンコーディングも指定できる。
区切り文字のマッチングを正則表現で指定できる。
詳しくは、https://docs.oracle.com/javase/jp/8/docs/api/java/util/Scanner.html

// System.in から数値を読み込み
Scanner sc1 = new Scanner(System.in);
int i = sc1.nextInt();

// File から構築
Scanner sc2 = new Scanner(new File("file.txt"));

// Scanner sc2 = new Scanner("file.txt")); とはできない。
// このようにした場合、"file.txt" という文字列を読もうとしてしまう。

// 区切りをコンマに変更
sc2.useDelimiter(",");

// 区切りごとに1行ずつ表示
while (sc2.hasNext())
{
    String str = sc2.next();
    System.out.println(str);
}

// sc1.close();
sc2.close();

利用の関係を表した図

java.io4.png

命名の法則

クラス名 分解 意味
FileInputStream File-InputStream File を InputStream に変換する。
InputStreamReader InputStream-Reader InputStream を Reader に変換する。
FileReader File-Reader File を Reader に変換する。