Java では元々 java.io.* に含まれる I/O ライブラリをサポートしてきましたが、Windows と Linux 系で扱いが異なったり、ファイル権限操作やシンボリックリンク操作に制約がありました。これを改善した NIO(New I/O) が java.nio.* でサポートされました。また、Java SE 7 からは NIO.2 と呼ばれるライブラリも追加され、大半は java.nio.file.* に含められています。現在では I/O(java.io.*) よりも NIO や NIO.2 (java.nio.*) を使用することが推奨されています。
古い書き方の場合、入出力に関するクラスの多くは使用が終わると close() する必要があります。
try { FileReader in = new FileReader("file.txt"); : in.close(); } catch (Exception e) { e.printStackTrace(); }
入出力に関するクラスの大半は Java 7 でサポートされた AutoCloseable インタフェースを実装しており、下記の様に記述することで close() を省略することができます。
try (FileReader in = new FileReader("file.txt")) { : } catch (Exception e) { e.printStackTrace(); }
バイナリファイルを1バイトずつ読み込みます。
import java.io.*; class Main { public static void main(String[] args) { try (FileInputStream in = new FileInputStream("file.bin")) { int ch; while ((ch = in.read()) != -1) { System.out.print(String.format("%02x ", Integer.valueOf(ch))); } System.out.println(""); } catch (Exception e) { e.printStackTrace(); } } }
バイナリファイルを1バイトずつ読み込みます。FileInputStream() だけだとファイルから1バイトずつ読み取るのに対して、BufferedInputStream を用いると 8192 バイトずつバッファリングしながら読み込むため、高速に読み込むことができます。
import java.io.*; class Main { public static void main(String[] args) { try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("file.bin"))) { int ch; while ((ch = bis.read()) != -1) { System.out.print(String.format("%02x ", Integer.valueOf(ch))); } System.out.println(""); } catch (Exception e) { e.printStackTrace(); } } }
バイナリファイルを1バイトずつ読み込みます。
import java.io.*; import java.nio.file.*; class Main { public static void main(String[] args) { Path path = Paths.get("file.bin"); try (InputStream is = Files.newInputStream(path)) { int ch; while ((ch = is.read()) != -1) { System.out.print(String.format("%02x ", Integer.valueOf(ch))); } System.out.println(""); } catch (Exception e) { e.printStackTrace(); } } }
バイナリファイルをバイト列としてすべて読み込みます。
import java.nio.file.*; class Main { public static void main(String[] args) { Path path = Paths.get("file.bin"); try { byte[] bytes = Files.readAllBytes(path); for (byte by : bytes) { System.out.print(String.format("%02x ", Integer.valueOf(0xFF & by))); } System.out.println(""); } catch (Exception e) { e.printStackTrace(); } } }
テキストファイルを1文字ずつ読み込みます。
import java.io.*; class Main { public static void main(String[] args) { try (InputStreamReader in = new InputStreamReader(new FileInputStream("file.txt"), "UTF-8")) { int ch; while ((ch = in.read()) != -1) { System.out.print(String.format("%04x ", Integer.valueOf(ch))); } System.out.println(""); } catch (Exception e) { e.printStackTrace(); } } }
UTF-8 の「あいう」という内容のファイルを読み込んだ場合、結果は次のようになります。3042 は「あ」、3044 は「い」、3046 は「う」の UTF-16 コードです。InputStreamReader を用いることで UTF-8 のファイルを Java の標準文字コードである UTF-16 に変換しながら読み込むことができました。
3042 3044 3046 000a
文字コードを省略した場合は、プラットフォームに依存したデフォルト(省略時の)文字コードで読み出されます。日本語 Windows の場合のデフォルト文字コードは MS932、Linux では UTF-8 になります。
InputStreamReader の面倒さを解消するために用意されたサブクラスです。InputStreamReader より簡単に扱えますが、文字コードを指定することができません。
import java.io.*; class Main { public static void main(String[] args) { try (FileReader in = new FileReader("file.txt")) { int ch; while ((ch = in.read()) != -1) { System.out.print(String.format("%04x ", Integer.valueOf(ch))); } System.out.println(""); } catch (Exception e) { e.printStackTrace(); } } }
テキストファイルを1行ずつ読み込みます。
import java.io.*; class Main { public static void main(String[] args) { try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } catch (Exception e) { e.printStackTrace(); } } }
テキストファイルを1行ずつ読み込みます。
import java.io.File; import java.util.Scanner; class Main { public static void main(String[] args) { try (Scanner in = new Scanner(new File("file.txt"))) { while (in.hasNextLine()) { String line = in.nextLine(); System.out.println(line); } } catch (Exception e) { e.printStackTrace(); } } }
BufferedReader より若干遅いですが、下記の様にしてキーボードからの入力を読み込むことができます。
Scanner in = new Scanner(System.in);
NIO では BufferedReader を簡単に使用するための newBufferedReader() をサポートしています。
import java.io.*; import java.nio.file.*; class Main { public static void main(String[] args) { Path path = Paths.get("file.txt"); try (BufferedReader br = Files.newBufferedReader(path)) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } catch (Exception e) { e.printStackTrace(); } } }
ファイルの文字コードを指定することもできます。
Files.newBufferedReader(path, StandardCharsets.UTF_8)) Files.newBufferedReader(path, Charset.forName("MS932"))
テキストファイルを1行ずつ読み込みます。
import java.util.stream.Stream; import java.nio.file.*; class Main { public static void main(String[] args) { Path path = Paths.get("file.txt"); try (Stream<String> stream = Files.lines(path)) { stream.forEach(line -> { System.out.println(line); }); } catch (Exception e) { e.printStackTrace(); } } }
ファイルの全行を行の配列として読み込みます。
import java.util.List; import java.nio.file.*; class Main { public static void main(String[] args) { Path path = Paths.get("file.txt"); try { List<String>lines = Files.readAllLines(path); for (String line : lines) { System.out.println(line); } } catch (Exception e) { e.printStackTrace(); } } }
バイナリファイルにバイト列を書き込みます。
import java.io.*; import java.nio.file.*; class Main { public static void main(String[] args) { Path path = Paths.get("file.txt"); try (BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(path))) { byte[] buf = { 0x41, 0x42, 0x43, 0x0a }; bos.write(buf); } catch (Exception e) { e.printStackTrace(); } } }
テキストファイルに1行ずつ書き込みます。
import java.io.*; import java.nio.file.*; class Main { public static void main(String[] args) { Path path = Paths.get("file.txt"); try (BufferedWriter bw = Files.newBufferedWriter(path)) { String line = "This is Japan.\n"; bw.write(line); } catch (Exception e) { e.printStackTrace(); } } }
テキストファイルに複数行まとめて書き込みます。
import java.util.List; import java.nio.file.*; import java.nio.charset.*; class Main { public static void main(String[] args) { Path path = Paths.get("file.txt"); try { List<String> lines = List.of("ABCDEFG", "HIJKLMN", "OPQRSTU"); Files.write(path, lines, StandardCharsets.UTF_8, StandardOpenOption.APPEND); } catch (Exception e) { e.printStackTrace(); } } }
第三引数には文字コードを指定します。省略すると OS 標準の文字コードとなります。第四引数以降(可変引数)には書込みオプションを指定します。
StandardOpenOption.APPEND 追記モードで書き込む StandardOpenOption.CREATE ファイルが存在しなければ作成する StandardOpenOption.CREATE_NEW ファイルが存在しなければ作成する。存在していればエラー StandardOpenOption.TRUNCATE_EXISTING ファイルが存在する場合は開いたときに0バイトにする StandardOpenOption.DELETE_ON_CLOSE ファイルを閉じる時に削除する StandardOpenOption.READ 読込みアクセス用に開く StandardOpenOption.WRITE 書込みアクセス用に開く StandardOpenOption.DSYNC 記憶装置に同期的に書き込む