Buffered Streamsでテキストデータの読み込み、書き込みを行う方法
Buffered Streamsとは?
Buffered Streamsとは、データを一定量バッファに溜め込んでから処理するため、I/Oの回数を減らし、効率的に読み書きすることができる。上記に記載の通り、bytesや文字端谷ではなく、文章ごとで読み込みができる。
ハンズオン
概要
今回はハンズオンで、以下の流れを確認する。
- 数千個の英単語が書かれたtxtファイルを読み込む
- 100個ずつ分けて、分割ファイルを作成する
- 作成したファイル内では、アルファベット順で並べられる。
詳細
フォルダ構造は以下の通り
- MakeShards.java
- unsorted.txt
二つ目のファイルがtxtファイルで、以下のような中身である。
pursuant
kinase
agencies
mineral
jar
conducted
past
tom
wx
tail
etc..
javaファイルを実行すると、shardsというフォルダが作成されて、shard00.txt、shard01.tx、etc.. といった形でtxtファイルが作成される。そして、その中身は以下の通りに、アルファベット順で記載される。
addressed
agencies
alexander
api
arrangement
attempting
author
beads
beats
bookmarks
etc..
プログラム作成
準備
まず、必要なライブラリをimportする。
import java.io.BufferedReader;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
次に、各txtファイルに記載される単語を100個に絞りたいので、以下の通り、SHARD_SIZEを定義する。
public final class MakeShards {
private static final int SHARD_SIZE = 100;
また、userから「どのテキストファイルを読み込むか」ということと「どのフォルダにアウトプットファイルを出力するか」ということをコマンドラインから入力して欲しいので、以下の通り記述する。こうすることで、一つ目のコマンド入力をinputファイル、二つ目をアウトプットフォルダと定義できる。
public static void main(String[] args) throws Exception {
if (args.length != 2) {
System.out.println("Usage: MakeShards [input file] [output folder]");
return;
}
Path input = Path.of(args[0]);
Path outputFolder = Files.createDirectory(Path.of(args[1]));
各ファイルに単語を追加
まずは、unsorted.txtファイルの読み込みをする。単語はnullになるまで、行ごとに読んこんでいく。
try (BufferedReader reader = Files.newBufferedReader(input)) {
int shardNum = 0;
String word = reader.readLine();
while (word != null) {
一番最初にprivate static final int SHARD_SIZE = 100;と記述しているので、100個を想定して、各配列を作成する。whileループでは、100個に達するかwordがなくなるまで、wordを読み込んで、リストに追加していく。
List<String> shard = new ArrayList<>(SHARD_SIZE);
while (shard.size() < SHARD_SIZE && word != null) {
shard.add(word);
word = reader.readLine();
}
shard.sort(String::compareTo);でアルファベット順に並べ替える。
shard.sort(String::compareTo);
次にここで、出力ファイルのパスを作成している。Path outputFolder = Files.createDirectory(Path.of(args[1]))にある通り、ここはユーザに入力してもらった[output folder]が出力されるコマンド。そして、getOutputFileName(shardNum)は、最初に設定したint shardNum = 0;が追加されていくイメージ。
つまりここでは、shardXX.TXTの形式で、追加されていく形となる。二桁になるのは、shard%02d.txtと記載されているから。
Path output = Path.of(outputFolder.toString(), getOutputFileName(shardNum));
そして、outputファイルが出来上がったので、writerで書き込んでいく。
try (Writer writer = Files.newBufferedWriter(output)) {
shardに単語が100個溜め込んでいるので、これを一つずつ書き込んでいく。最後にlineSeparatorを使って、改行していく。
for (int i = 0; i < shard.size(); i++) {
writer.write(shard.get(i));
if (i < shard.size() - 1) {
writer.write(System.lineSeparator());
}
}
}
最後にシャード番号を受け取って、shardXX.txtのように、シャード番号に基づいたファイル名を出力する。
private static String getOutputFileName(int shardNum) {
return String.format("shard%02d.txt", shardNum);
Discussion