社会人のメモ帳

忘れたくないことアレコレ

【第5週】第5章:ファイルの入出力を実装してみる【Java Gold合格へ向けて】

PREV | LIST | NEXT

ファイルの入出力ストリームとは

読み書きの向きに応じて入力ストリーム出力ストリームに、読み書きを行うデータサイズに応じてバイトストリームキャラクタストリームに分類される。

クラス名 説明 キャラクタストリーム or バイトストリーム 入力ストリーム or 出力ストリーム
FileInputStream ファイルからbyte単位の読み込みを行うストリーム バイト
ストリーム
入力
ストリーム
FileOutputStream ファイルからbyte単位の書き出しを行うストリーム バイト
ストリーム
出力
ストリーム
FileReader ファイルからchar単位の読み込みを行うストリーム キャラク
ストリーム
入力
ストリーム
FileWriter ファイルからchar単位の書き出しを行うストリーム キャラク
ストリーム
出力
ストリーム

ファイルの入出力を実装してみる

FileOutputStream

ファイルへのbyte単位の書き出しを行い、新規ファイルの作成を行う。内容としては「a(改行)b(改行)c」となることを期待する。

public class Main {
    public static void main(String[] args) throws IOException {
        Main.outputStreamTest();
    }

    static void outputStreamTest() throws IOException {
        System.out.println("=== outputStreamTest ===");
        FileOutputStream stream = null;
        OutputStreamWriter iSWriter = null;
        try {
            stream = new FileOutputStream("C: (ファイルパス) outputTest.txt");
            iSWriter = new OutputStreamWriter(stream, StandardCharsets.UTF_8);
            iSWriter.write("a\n");
            iSWriter.write("b\n");
            iSWriter.write("c");
        } catch (IOException e) {
            System.out.println("エラー発生:"+e.getMessage());
        } finally {
            if (Objects.nonNull(iSWriter)) iSWriter.close();
            if (Objects.nonNull(stream)) stream.close();
            System.out.println("ファイル クローズ済");
        }
    }
}

実行結果

=== outputStreamTest ===
ファイル クローズ済

出力されたファイル:outputTest.txt

a
b
c

FileInputStream

FileOutputStreamで出力されたoutputTest.txtの中身(=「a(改行)b(改行)c」)を取得する。 それぞれbyte単位で取得した値をHexに変換した値と、char型に変換した値をそれぞれ出力している。 Hex:61 = a, 62 = b, 63 =c, a =改行コード

public class Main {
    public static void main(String[] args) throws IOException {
        Main.inputStreamTest();
    }

    static void inputStreamTest() throws IOException {
        System.out.println("=== inputStreamTest ===");
        FileInputStream stream = null;
        InputStreamReader iSReader = null;
        try {
            stream = new FileInputStream("C: (ファイルパス) outputTest.txt");
            iSReader = new InputStreamReader(stream, StandardCharsets.UTF_8);
            int data;
            while ((data = iSReader.read()) != -1) {
                System.out.println("[toHexString]" + Integer.toHexString(data));
                System.out.println("(char)" + (char) data);
            }
        } catch (IOException e) {
            System.out.println("エラー発生:" + e.getMessage());
        } finally {
            if (Objects.nonNull(iSReader)) iSReader.close();
            if (Objects.nonNull(stream)) stream.close();
            System.out.println("ファイル クローズ済");
        }
    }
}

実行結果 Hex:61 = a, 62 = b, 63 =c, a =改行コード

=== inputStreamTest ===
[toHexString]61
(char)a
[toHexString]a
(char)

[toHexString]62
(char)b
[toHexString]a
(char)
 
[toHexString]63
(char)c
ファイル クローズ済

FileWriter

ファイルへのchar単位の書き出しを行い、新規ファイルの作成を行う。内容としては「a(改行)b(改行)c」となることを期待する。

public class Main {
    public static void main(String[] args) throws IOException {
        Main.fileWriterTest();
    }

    static void fileWriterTest() throws IOException {
        System.out.println("=== fileWriterTest===");
        FileWriter iSWriter = null;
        try {
            File file = new File("C: (ファイルパス) writeTest.txt");
            iSWriter = new FileWriter(file, StandardCharsets.UTF_8);
            iSWriter.write("a\n");
            iSWriter.write("b\n");
            iSWriter.write("c");
        } catch (IOException e) {
            System.out.println("エラー発生:"+e.getMessage());
        } finally {
            if (Objects.nonNull(iSWriter)) iSWriter.close();
            System.out.println("ファイル クローズ済");
        }
    }
}

実行結果

=== fileWriterTest ===
ファイル クローズ済

出力されたファイル:outputTest.txt

a
b
c

FileReader

FileWriterで出力されたoutputTest.txtの中身(=「a(改行)b(改行)c」)を取得する。 それぞれbyte単位で取得した値をHexに変換した値と、char型に変換した値をそれぞれ出力している。

public class Main {
    public static void main(String[] args) throws IOException {
        Main.fileReaderTest();
    }

    static void fileReaderTest() throws IOException {
        System.out.println("=== fileReaderTest ===");
        FileReader iSReader = null;
        try {
            File file = new File("C: (ファイルパス) writeTest.txt");
            iSReader = new FileReader(file, StandardCharsets.UTF_8);
            int data;
            while ((data = iSReader.read()) != -1) {
                System.out.println("[toHexString]" + Integer.toHexString(data));
                System.out.println("(char)" + (char) data);
            }
        } catch (IOException e) {
            System.out.println("エラー発生:"+e.getMessage());
        } finally {
            if (Objects.nonNull(iSReader)) iSReader.close();
            System.out.println("ファイル クローズ済");
        }
    }
}

実行結果 Hex:61 = a, 62 = b, 63 =c, a =改行コード

=== fileReaderTest ===
[toHexString]61
(char)a
[toHexString]a
(char)

[toHexString]62
(char)b
[toHexString]a
(char)
 
[toHexString]63
(char)c
ファイル クローズ済

まとめ

読み書きするデータサイズが異なるだけで、処理の順序などはそれぞれで違いはないようだ。注意すべき点として改行コードなども読み出し、書き込みでは考慮する必要があることや、例外処理などもまた別途で考慮する必要があることなどが挙げられる。今回はfinallyを使ってクローズ処理を実装し、NULLの場合なども考慮してExceptionで落ちないようにし、例外発生時にはその内容をログとして出力できるように実装している。