Javaでファイル操作を行う際、FileChannel.open() と Files.write() はよく使われますが、オプション(OpenOption)を省略した場合の挙動が異なるため注意が必要です。
チャネル系 API (FileChannel.open / Files.newByteChannel)
options を省略した場合 → 読み取り専用 (read‑only)
書き込みを行うには、StandardOpenOption.WRITE や CREATE などを明示的に指定する必要があります。
ファイルが存在しない場合は NoSuchFileException。
Path path = Paths.get("file.txt");
// 省略時は読み取り専用
try (FileChannel fc = FileChannel.open(path)) {
fc.write(ByteBuffer.wrap("Hello".getBytes()));
// → NonWritableChannelException が発生
} catch (IOException e) {
e.printStackTrace();
}
// 書き込みしたい場合は明示的に指定
try (FileChannel fc = FileChannel.open(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE)) {
fc.write(ByteBuffer.wrap("Hello".getBytes()));
} catch (IOException e) {
e.printStackTrace();
}
書き込み系ユーティリティ (Files.write / Files.newOutputStream)
options を省略した場合 → 書き込み可 (WRITE) + CREATE + TRUNCATE_EXISTING
ファイルがなければ作成され、既存ファイルは中身削除して上書き。
上書きせず追記したい場合は StandardOpenOption.APPEND を明示的に指定。
Path path = Paths.get("out.txt");
// 省略時でも書き込み可
Files.write(path, "Hello".getBytes());
// → ファイルなければ作成、既存ファイルは上書き
// 追記したい場合
Files.write(path, "World".getBytes(), StandardOpenOption.APPEND);
省略時モードのまとめ
| API | オプション省略時のモード | ファイルが存在しない場合 | 既存ファイルの扱い |
|---|---|---|---|
| FileChannel.open / Files.newByteChannel | 読み取り専用 (READ) | 例外 | 書き込み不可 |
| Files.write / Files.newOutputStream / BufferedWriter | 書き込み可 + CREATE + TRUNCATE_EXISTING | 作成される | 中身削除して上書き |
実務上のポイント
チャネル系は省略=READ
書き込みしたければ明示的に WRITE を指定
書き込み系は省略=WRITE+CREATE+TRUNCATE_EXISTING
上書きされるので注意
追記したい場合は APPEND を指定
ファイル操作は 例外処理は必須