目的
キーが1対1の関係になっている2つのファイルを1行ずつ読みだし内容を比較する。その比較結果を別のファイルに出力するプログラムをJavaで作成する。
要件
〇入力ファイル
・在庫ファイル
商品コード
在庫数
・注文ファイル
商品コード
注文数
※それぞれ、商品コードで一意、昇順になっている。
〇出力ファイル
・新在庫ファイル
商品コード
在庫数
・エラーファイル
商品コード
注文数
新在庫ファイル・・・入力ファイルの在庫と注文を突合して、在庫数から注文数を引いた数量を記録する
エラーファイル・・・注文に対して、在庫がない、在庫が足りない場合はエラーとし、当ファイルに出力する
〇その他
入力ファイルのサイズが大きいため、1行ずつ読み込んで処理していく必要がある。
実装例
public void matching() {
try (var stockFile = Files.newBufferedReader(Paths.get("src/stock.txt"));
var orderFile = Files.newBufferedReader(Paths.get("src/order.txt"));
var newStockFile = Files.newBufferedWriter(Paths.get("src/newStock.txt"));
var errorOrderFile = Files.newBufferedWriter(Paths.get("src/errorOrder.txt"));) {
// 入力ファイルの1行目を読み込む
// 文字列からオブジェクトに変換する
Stock stock = Stock.createFromLine(stockFile.readLine());
Order order = Order.createFromLine(orderFile.readLine());
// どちらかのファイルの行があるうちは処理を続ける
while (stock.getKey() < Integer.MAX_VALUE || order.getKey() < Integer.MAX_VALUE) {
// 比較するコードを取得。(この例ではコードを数値としている)
// コードで昇順になっているのでコードの大小を比較すれば、
// 一方のファイルにしかない商品もわかる
int stockKey = stock.getKey();
int orderKey = order.getKey();
if (stockKey - orderKey == 0) {
// コードが一致
int qty = stock.getQuantity() - order.getQuantity();
if (qty < 0) {
// 在庫不足
// エラーファイル出力
errorOrderFile.write(order.toErrorOrder("01").toLine());
errorOrderFile.newLine();
} else {
stock.setQuantity(qty);
}
// オブジェクトから1行分の文字列を生成し、書き出す
newStockFile.write(stock.toNewStock().toLine());
newStockFile.newLine();
// 次の行を読み込む
stock = Stock.createFromLine(stockFile.readLine());
order = Order.createFromLine(orderFile.readLine());
} else if (stockKey - orderKey > 0) {
// 商品なし
// エラーファイル出力
errorOrderFile.write(order.toErrorOrder("02").toLine());
errorOrderFile.newLine();
// 次の行を読み込む
order = Order.createFromLine(orderFile.readLine());
} else {
// 注文なし
newStockFile.write(stock.toNewStock().toLine());
newStockFile.newLine();
// 次の行を読み込む
stock = Stock.createFromLine(stockFile.readLine());
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
※他にも「var」宣言を使える箇所があるが、わかりやすくするため、あえて通常の宣言にしている。
@Builder
@Data
public class Order {
private String category;
private String code;
private Integer quantity;
public Integer getKey() {
if (category == null && code == null) {
return Integer.MAX_VALUE;
} else {
return Integer.valueOf(category + code);
}
}
public ErrorOrder toErrorOrder(String errorCode) {
return ErrorOrder.builder()
.category(category)
.code(code)
.quantity(quantity)
.errorCode(errorCode)
.build();
}
public static Order createFromLine(String line) {
if (line == null) {
return Order.builder().build();
} else if (line.length() < 35) {
throw new IllegalArgumentException();
}
return Order.builder()
.category(line.substring(4, 5))
.code(line.substring(6, 7))
.quantity(Integer.valueOf(line.substring(8, 9)))
.build();
}
}