環境
JDK 17
主要なクラス・インタフェース
ファイル操作に関するクラス・インタフェースの多くはjava.nio.file
パッケージに属しています。
これらのクラス・インタフェースを総称して「NIO.2」と呼ばれます。
Path
インタフェース
Path
インタフェースは、名前の通りファイルやディレクトリのパスを表します。Path.of("ファイルやディレクトリのパス")
でPath
オブジェクトを生成できます。
Path targetFile = Path.of("/tmp/test/sample.txt");
Files
クラス
ファイルまたはディレクトリに関する操作(読み込みや書き込みなど)はFiles
クラスのstaticメソッドとしてまとまっています。
いろんなメソッドが用意されているので、ぜひJavadocを一通り眺めてみてください!
文字コード
文字コードはCharset
抽象クラスが表します。Charset.forName("文字コード名")
で、指定した文字コードを表すCharset
オブジェクトを生成できます。
Charset cs = Charset.forName("MS932");
Charset cs = Charset.forName("EUC-JP");
文字コード名が正しくない場合は
UnsupportedCharsetException
がスローされます。
UTF-8やUTF-16などを指定する場合はStandardCharsets
クラスの定数を利用できます。
Charset cs = StandardCharsets.UTF_8;
Charset cs = StandardCharsets.UTF_16;
テキストファイルの読み込み
あいうえお
かきくけこ
さしすせそ
1行ずつ読み込んで加工する
Files.lines()
メソッドを利用すると、各行を要素に持つStream<String>
を取得できます。
今回は各行を[]
で囲うように変換します。
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Path targetFile = Path.of("/tmp/test/sample.txt");
// 処理終了後に自動的にStreamがclose()されるようにtry-with-resourcesを利用
try (Stream<String> stream = Files.lines(targetFile, StandardCharsets.UTF_8)) {
// 各行を[]で囲う
List<String> list = stream.map(line -> "[" + line + "]")
.toList();
for (String line : list) {
// 読み込んだ行に対して何らかの処理を行う
// 今回はサンプルなので表示するだけ
System.out.println(line);
}
} catch (IOException e) {
// 業務コードでe.printStackTrace()を使うことはめったにありません。
// 業務では各プロジェクトのルールに合わせて、例外の再スローやログの出力などを行ってください。
e.printStackTrace();
}
}
}
引数が
Path
のみで文字コードを指定しないlines()
メソッドもあります。このメソッドでは、文字コードはUTF-8になります。
[あいうえお]
[かきくけこ]
[さしすせそ]
BufferedReaderを使う
ほとんどの場合はFiles.lines()
メソッドで事足りると思います。
しかし、どうしても従来のBufferedReader
を使いたい場合は、Files.newBufferedReader()
メソッドで取得できます。
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
public class Main {
public static void main(String[] args) {
Path targetFile = Path.of("/tmp/test/sample.txt");
// 処理終了後に自動的にBufferedReaderがclose()されるようにtry-with-resourcesを利用
try (BufferedReader reader = Files.newBufferedReader(
targetFile, StandardCharsets.UTF_8)) {
// reader.readLine()で次の1行を読み込む(ファイルの末尾に到達した場合はnullを返す)
for (String line; (line = reader.readLine()) != null;) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
あいうえお
かきくけこ
さしすせそ
全行を保持するListを生成する
Files.readAllLines()
を利用します。
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
public class Main {
public static void main(String[] args) {
Path targetFile = Path.of("/tmp/test/sample.txt");
try {
// 1要素=1行であるListを生成する
List<String> lines = Files.readAllLines(targetFile, StandardCharsets.UTF_8);
for (String line : lines) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
あいうえお
かきくけこ
さしすせそ
このメソッドはファイルの全内容を一気に読み込むので、ファイルが非常に大きい場合に
OutOfMemoryError
を引き起こす可能性があります。テキストファイルのサイズが実行環境のメモリ量より十分に小さい場合のみ、このメソッドを利用してください。
ファイルの全内容を1つの文字列として取得する
Files.readString()
を利用します。
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
public class Main {
public static void main(String[] args) {
Path targetFile = Path.of("/tmp/test/sample.txt");
try {
String content = Files.readString(targetFile, StandardCharsets.UTF_8);
System.out.println(content);
} catch (IOException e) {
e.printStackTrace();
}
}
}
あいうえお
かきくけこ
さしすせそ
このメソッドも、ファイルの全内容を一気に読み込むので注意してください。
テキストファイルの書き込み
あいうえお
かきくけこ
さしすせそ
StandardOpenOption
StandardOpenOption
列挙型は、ファイルの開き方および作成方法を表します。
後述するFiles
クラスの各メソッドでは、最後の引数にStandardOpenOption
を指定します(可変長引数なので複数指定可能)。
-
CREATE
- ファイルが存在しない場合は新規作成します。
- ファイルが存在する場合は何もしません。
-
CREATE_NEW
- ファイルが存在しない場合は新規作成します。
- ファイルが存在する場合は例外がスローされます。
-
APPEND
- 既存の内容の最後に追記します。
-
TRUNCATE_EXISTING
- 既存の内容を上書きします。
1行だけ書き込む(追記)
Files.writeString()
を利用します。
第4引数(可変長)にStandardOpenOption.CREATE
(ファイルが存在する場合に例外にするならStandardOpenOption.CREATE_NEW
)・StandardOpenOption.APPEND
を指定すると、ファイル末尾への追記ができます。
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
public class Main {
public static void main(String[] args) {
Path targetFile = Path.of("/tmp/test/sample.txt");
try {
Files.writeString(targetFile, "たちつてと", StandardCharsets.UTF_8,
StandardOpenOption.CREATE,
StandardOpenOption.APPEND);
} catch (IOException e) {
e.printStackTrace();
}
}
}
あいうえお
かきくけこ
さしすせそ
たちつてと
1行だけ書き込む(上書き)
Files.writeString()
メソッドを利用します。
第4引数(可変長)にStandardOpenOption.CREATE
(ファイルが存在する場合に例外にするならStandardOpenOption.CREATE_NEW
)・StandardOpenOption.TRUNCATE_EXISTING
を指定すると、上書きになります。つまり、以前のファイルの内容は削除されます。
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
public class Main {
public static void main(String[] args) {
Path targetFile = Path.of("/tmp/test/sample.txt");
try {
Files.writeString(targetFile, "たちつてと", StandardCharsets.UTF_8,
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
}
}
}
たちつてと
複数行を一気に書き込む(追記)
Files.write()
を利用します。
第4引数(可変長)にStandardOpenOption.CREATE
(ファイルが存在する場合に例外にするならStandardOpenOption.CREATE_NEW
)・StandardOpenOption.APPEND
を指定すると、ファイル末尾への追記ができます。
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.List;
public class Main {
public static void main(String[] args) {
Path targetFile = Path.of("/tmp/test/sample.txt");
try {
List<String> lines = List.of("たちつてと", "なにぬねの", "はひふへほ");
Files.write(targetFile, lines, StandardCharsets.UTF_8,
StandardOpenOption.CREATE,
StandardOpenOption.APPEND);
} catch (IOException e) {
e.printStackTrace();
}
}
}
あいうえお
かきくけこ
さしすせそ
たちつてと
なにぬねの
はひふへほ
複数行を一気に書き込む(上書き)
第4引数(可変長)にStandardOpenOption.CREATE
(ファイルが存在する場合に例外にするならStandardOpenOption.CREATE_NEW
)・StandardOpenOption.TRUNCATE_EXISTING
を指定すると、上書きになります。
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.List;
public class Main {
public static void main(String[] args) {
Path targetFile = Path.of("/tmp/test/sample.txt");
try {
List<String> lines = List.of("たちつてと", "なにぬねの", "はひふへほ");
Files.write(targetFile, lines, StandardCharsets.UTF_8,
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
}
}
}
たちつてと
なにぬねの
はひふへほ
書き込み時の改行コードを明示的に指定
writeString()
・write()
では、改行コードは実行したOSのデフォルト(macOSとLinuxはLF、WindowsはCRLF)となります。
デフォルトでない改行コードを指定したい場合は、BufferedWriterクラスのwrite()メソッド
を利用します。
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.List;
public class Main {
public static void main(String[] args) {
Path targetFile = Path.of("/tmp/test/sample.txt");
try (BufferedWriter bufferedWriter = Files.newBufferedWriter(targetFile,
StandardCharsets.UTF_8,
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING)) {
List<String> lines = List.of("たちつてと", "なにぬねの", "はひふへほ");
for (String line : lines) {
bufferedWriter.write(line);
bufferedWriter.write("\r\n"); // 改行コードにCRLFを指定(LFの場合は"\n")
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
たちつてと
なにぬねの
はひふへほ
StandardOpenOption
はCREATE_NEW
やAPPEND
でもOKです。