ホーム > Java > 第9章-3 ストリーム

Java -ストリーム-

以前のプログラム言語では、ファイルからデータを読み込む場合は、ファイル用のAPIを キーボードからデータを読み込む場合は、キーボード用のAPIをというように、入力するデバイス ごとに違った読み込み処理を記述する必要がありましたが、最近のプログラム言語では、 共通のAPIを使ってコードを記述できるものが多くなってきました。

Javaでは入出力データをストリームという概念で扱い、処理の記述を共通のAPIを 利用することができます。

ストリーム

ストリームとは、データの流れとデータが流れる道を意味します。

Javaでは、「ファイルへ文字の書き込むためのストリーム」を java.io.FileWriterクラス
「ファイルから文字を読み込むためのストリーム」を java.io.FileReaderクラスとして用意されています。

それぞれのクラスのオブジェクトがストリームとなり、そのメソッドを利用して書き込み、読み込みを行います。

ファイルに文字を書き込む場合

処理の手順

  1. java.io.FileWriterクラスのオブジェクトを生成(ストリーム生成)
    ストリームの生成にはコンストラクタを利用します。
    引数には、ファイルの物理パスやファイル名を文字列またはFileオブジェクトで指定しますが、ディレクトリやファイルが 存在していなくても構いません。
    しかし、指定した名前がディレクトリである場合、ファイルが作成できない場合、または何らかの理由で開くことが できない場合には例外が発生します。
    FileWriterクラスのコンストラクタ
    • FileWriter(String fileName) throws IOException
    • FileWriter(String fimeName, boolean append) throws IOException
      引数appendがtrueの場合、データはファイルの先頭ではなく最後に書き込まれます。
    • FileWriter(File file) throws IOException
    • FileWriter(File file, boolean append) throws IOException
      引数appendがtrueの場合、データはファイルの先頭ではなく最後に書き込まれます。
  2. java.io.FileWriterクラスのメソッドを利用して文字の書き込み

    FileWriterクラスは、java.io.OutputStreamWriterクラスのサブクラスとして定義されており、以下の階層を持っています。

    Writerクラスから継承するwriteメソッド

    メソッド 説明
    void write(char[] cbuf) throws IOException 文字配列を書き込む
    void write(String str) throws IOException 文字列を書き込む

    OutputStreamWriterクラスから継承するメソッド

    メソッド 説明
    void write(int c) throws IOException 単一の文字を書き込む
    void write(char[] cbuf,int off,int len) throws IOException 文字配列cbufの一部(off番目からlenの文字数分)を書き込む
    void write(String str,int off,int len) throws IOException 文字列strの一部(off番目からlenの文字数分)を書き込む。
    lenに負の数を指定した場合、実行時にjava.lang.
    IndexOutOfBoundsExceptionが発生する。

サンプル

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class Sample9_3 {
    public static void main(String []args){
        String path="./data/test.txt";
        try {
            File file=new File(path);
            FileWriter fw=new FileWriter(file);
            fw.write("Hello");
            fw.flush();
            fw.close();
            System.out.println("書き込みが完了しました");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

ファイル入出力では、例外をスローするのでtry~catch文による例外処理が必須となります。
FileWriterオブジェクトの生成にはコンストラクタを利用します。
Filewriterはファイルへのストリームを表し、ストリームの生成時にファイルを開きます。
ファイルが存在しない場合は、ファイルを新規に作成します。

文字を書き込む際には、writeメソッドを利用します。FileWriterは開いたファイルの先頭から 文字を書き込みます。

書き込む際に多少のバッファリングが発生するため、flushメソッドを呼び出ることでバッファ内のデータを 明示的に書き込むことができます。

ファイルの操作が終了したらファイルを閉じます。
アプリケーションの終了時に自動的のファイルは閉じられますが、メモリなどのリソースを有効利用するため closeメソッドを呼び出し、ファイルを閉じる必要があります。
通常closeメソッドの呼び出しは、finallyブロックに記述します。

ファイルから文字を読み込む場合

処理の手順

  1. java.io.FileReaderクラスのオブジェクトを生成(ストリーム生成)
    書き込みの際のFileWriterクラス同様にストリームの生成にはコンストラクタを利用します。
    引数には、ファイルの物理パスやファイル名を文字列またはFileオブジェクトで指定します
    FileWriterとの違いは、指定したファイルがない場合は、例外が発生します。
    FileReaderクラスのコンストラクタ
    • FileReader(String fileName) throws FileNotFoundException
    • FileReader(File file) throws FileNotFoundException
  2. java.io.FileWriterクラスのメソッドを利用して文字の書き込み

    FileReaderクラスは、java.io.InputStreamReaderクラスのサブクラスとして定義されており、以下の階層を持っています。

    Readerクラスから継承するreadメソッド
    メソッド 説明
    int read (char[] cbuf) throws IOExcepion 配列cbufに文字を読み込む。
    戻り値は、読み込まれた文字数で、ストリームの終わりに達した場合は、-1を返す
    InputSteramReaderクラスから継承するreadメソッド
    メソッド 説明
    int read() throws IOException 単一の文字を読み込んで返す。
    ストリームの終わりに達した場合は、-1を返す
    int read (char[] cbuf,int offset, int length) throws IOException 文字配列cbufの一部(offset番目からlength文字数分)に文字を読み込む。
    戻り値は読み込まれた文字数で、ストリームの終わりに達した場合は、-1を返す

サンプル

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class Sample10_4 {
    public static void main(String [] args){
        String path="./data/test.txt";
        File file=new File(path);
        FileReader fr=null;
        int c=0;

        try {
            fr=new FileReader(file);
            while((c=fr.read())!=-1){
                System.out.print((char)c);
            }
            fr.close();
            System.out.println();
            System.out.println("読み込みが完了しました");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

ファイルの読み込みを行うためにはreadメソッドを利用します

FileReaderでは、ファイルを開くと先頭から読み込み、ファイルの終端に達して-1を返すまで読みます。
読み込んだ1文字はint型で返されるため、int型の変数で受け取り、char型にキャストして出力しています。

ファイルの書き込み、読み込みをする際利用するストリームは別のクラスとして用意されていますが、対になっています。

FileWriter、FileReaderを利用した場合、基本的には1文字ずつの入出力となり、効率が悪くなります。
そのためJavaには、より効率処理できるストリームが用意されています。