ぺーぺーSEのブログ

備忘録・メモ用サイト。

Javaの入出力ストリーム

入出力ストリームに関するjava.ioパッケージについて。
詳細は下記のAPI仕様書
http://java.sun.com/javase/ja/6/docs/ja/api/java/io/package-summary.html

バイトストリーム

バイト入力ストリーム(抽象クラスjava.io.InputStreamのサブクラス)
  • FileInputStream
    • ファイルシステムから入力バイトを取得する。
    • イメージデータなどの raw バイトのストリームを読み込むときに使用する。文字のストリームを読み込むときは、FileReader を使用する。
  • ObjectInputStream
    • 事前に ObjectOutputStream を使って作成されたプリミティブデータとプリミティブオブジェクトを直列化復元する。
    • ObjectOutputStream と ObjectInputStream は、FileOutputStream または FileInputStream とともに使えば、アプリケーションに、オブジェクトのグラフのための持続的なストレージを提供することができる。
  • DataInputStream
    • データ入力ストリームにより、アプリケーションは、プリミティブ型の Java データを基本となる入力ストリームからマシンに依存せずに読み込むことができる。
バイト出力ストリーム(抽象クラスjava.io.OutputStreamのサブクラス)
  • FileOutputStream
    • ファイル出力ストリームは、File または FileDescriptor にデータを書き込むための出力ストリーム。
  • ObjectOutputStream
    • ObjectOutputStream は、基本データ型とJavaオブジェクトのグラフをOutputStreamに書きむ。
    • これらのオブジェクトを読み込む (再構築する) には ObjectInputStream を使う。
  • DataOutputStream
    • データ出力ストリームを使うと、アプリケーションはプリミティブ型の Java データを移植性のある形で出力ストリームに書き込むことができる。
    • アプリケーションはデータ入力ストリームを使ってデータを読み戻すことができる。

文字ストリーム

文字入力ストリーム(抽象クラスjava.io.Readerのサブクラス)
  • BufferedReader
    • 文字、配列、行をバッファリングすることによって、文字型入力ストリームからテキストを効率良く読み込む。
  • LineNumberReader
    • 行番号を追跡して管理する、バッファリングされた文字入力ストリーム。
    • このクラスには、現在の行番号を設定するsetLineNumber(int)メソッドと、現在の行番号を取得するgetLineNumber()メソッドが定義されている。
  • InputStreamReader
    • バイトストリームから文字ストリームへの橋渡しの役目を持つ。バイトを読み込み、指定されたcharsetを使用して文字に変換する。
  • FileReader
    • 文字ファイルを読み込むための簡易クラス。
    • このクラスのコンストラクタは、デフォルトの文字エンコーディングとデフォルトのbyteバッファのサイズが適切に設定されていることを前提としている。
    • これらの値を自分で指定するには、FileInputStream上にInputStreamReaderを構築する。
  • StringReader
    • ソースが文字列の文字ストリーム。
文字出力ストリーム(抽象クラスjava.io.Writerのサブクラス)
  • BufferedWriter
    • 文字をバッファリングすることによって、文字、配列、または文字列を効率良く文字型出力ストリームに書き込む。
    • システムプロパティのline.separatorで定義される行区切り文字はプラットフォームに依存するため、newLine()メソッドが提供されている。
  • OutputStreamWriter
    • 文字ストリームからバイトストリームへの橋渡しの役目を持つ。バイトストリームに書き込まれた文字は、指定されたcharsetを使用してバイトに符号化される。
  • FileWriter
    • 文字ファイルを書き込むための簡易クラス。
    • このクラスのコンストラクタは、デフォルトの文字エンコーディングとデフォルトの byte バッファーのサイズが許容できることを前提としている。
    • これらの値を自分で指定するには、FileOutputStream上にOutputStreamWriterを構築する。
  • PrintWriter
    • オブジェクトの書式付き表現をテキスト出力ストリームに出力する。このクラスは、PrintStreamにあるprintメソッドをすべて実装する。
  • StringWriter
    • 出力を文字列バッファーに集める文字ストリーム。この文字列バッファーを使って文字列を構築する。

サンプルコード

画像のバイナリをバイトストリームで読み取って、そのまま画像出力とテキストにバイナリ文字を出力してみる。

package jp.sample1;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Main {

    public static void main(String[] args) {
        try {
            // 画像をバイトストリームで読み込む
            InputStream in = new FileInputStream("C:\\tmp\\before.jpg");

            // 画像をそのままバイトストリームで出力
            OutputStream pic = new FileOutputStream("C:\\tmp\\after.jpg");

            // 画像のバイナリ文字列をバイトストリームで出力
            OutputStream bin = new FileOutputStream("C:\\tmp\\pinBin.txt");

            // 読み込み処理
            int num;
            while ((num = in.read()) != -1) {
                // 書き込み処理
                pic.write(num);
                bin.write(num);
            }

            // クローズ処理
            in.close();
            pic.close();
            bin.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

バイトストリームでテキストを読んで、バイトストリームでファイル出力してみる。
(あえて、文字ストリームを使わずに)

package jp.sample2;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Main {

    public static void main(String[] args) {
        try {
            // テキストをバイトストリームで読み込む
            InputStream in = new FileInputStream("C:\\tmp\\before.txt");

            // バイナリをそのままバイトストリームで出力
            OutputStream out = new FileOutputStream("C:\\tmp\\after.txt");

            // 読み込み処理
            int num;
            while ((num = in.read()) != -1) {
                // 書き込み処理
                out.write(num);
            }

            // クローズ処理
            in.close();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

使い方の方針

■1バイト・1文字ずつ読み書きするストリームクラス

読み込み 書き込み
バイトストリーム InputStream OutputStream
文字ストリーム Reader Writer

上記を使用すると1バイト、1文字ごとにディスクにアクセスするため低速である。
なので、下記のバッファを行うストリームクラスを利用する。

■バッファリングを行い読み書きするストリームクラス

読み込み 書き込み
バイトストリーム BufferedInputStream BufferedOutputStream
文字ストリーム BufferedReader BufferedWriter

参考:
http://builder.japan.zdnet.com/java/20363416/
http://www.tohoho-web.com/java/file.htm
http://www.javaroad.jp/java_io2.htm