ファイルの入出力ストリームとは
読み書きの向きに応じて入力ストリームと出力ストリームに、読み書きを行うデータサイズに応じてバイトストリームとキャラクタストリームに分類される。
クラス名 | 説明 | キャラクタストリーム 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で落ちないようにし、例外発生時にはその内容をログとして出力できるように実装している。