data/transactions.csv 를 읽어 type 이 WITHDRAW 인 행만 data/withdraws.csv 로 뽑아내는 프로그램을 작성하세요. 헤더는 유지하고, 메모리에 파일 전체를 올리지 않아야 하며, 출력은 임시 파일을 거쳐 원자적으로 이동해야 합니다. 마지막에 "입력 N건 중 M건 추출" 을 출력하세요.
Path src = Path.of("data/transactions.csv");
Path dest = Path.of("data/withdraws.csv");
Path tmp = dest.resolveSibling("withdraws.csv.tmp");
long total = 0, picked = 0;
try (BufferedReader r = Files.newBufferedReader(src, StandardCharsets.UTF_8);
BufferedWriter w = Files.newBufferedWriter(tmp, StandardCharsets.UTF_8)) {
String header = r.readLine();
w.write(header); w.newLine();
String line;
while ((line = r.readLine()) != null) {
total++;
List<String> f = CsvParser.parseLine(line);
if ("WITHDRAW".equals(f.get(3))) {
w.write(line); w.newLine();
picked++;
}
}
}
Files.move(tmp, dest, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
System.out.printf("입력 %,d건 중 %,d건 추출 -> %s%n", total, picked, dest);
// 출력: 입력 100,000건 중 60,1xx건 추출 -> data\withdraws.csvFiles.walk 를 사용해 data/ 아래(하위 폴더 포함) 모든 .csv 파일의 이름과 크기(KB)를 크기 내림차순으로 출력하고, 합계를 출력하세요. 스트림은 반드시 닫아야 합니다.
record FileInfo(Path path, long bytes) {}
List<FileInfo> csvs;
try (Stream<Path> walk = Files.walk(Path.of("data"))) {
csvs = walk.filter(Files::isRegularFile)
.filter(p -> p.toString().endsWith(".csv"))
.map(p -> {
try { return new FileInfo(p, Files.size(p)); }
catch (IOException e) { throw new UncheckedIOException(e); }
})
.sorted(Comparator.comparingLong(FileInfo::bytes).reversed())
.toList();
}
long sum = 0;
for (FileInfo f : csvs) {
System.out.printf("%-40s %,8d KB%n", f.path(), f.bytes() / 1024);
sum += f.bytes();
}
System.out.printf("합계 %,d KB (%d개 파일)%n", sum / 1024, csvs.size());
// 출력:
// data\merged.csv 4,309 KB
// data\transactions.csv 4,309 KB
// data\parts\part-000.csv 1,077 KB
// ...
// 합계 13,xxx KB (8개 파일)고정길이 전문 data/transactions.txt 를 읽어 날짜별 입금 합계를 계산하고, 결과를 날짜(8),합계(15, 우측정렬 0패딩) 형식의 고정길이 파일 data/daily_deposit.txt 로 쓰세요. String.format 을 사용하고, 결과 파일의 모든 줄이 정확히 23자인지 검증하는 코드도 포함하세요.
Map<String, Long> byDate = new TreeMap<>();
try (Stream<String> lines = Files.lines(Path.of("data/transactions.txt"), StandardCharsets.US_ASCII)) {
lines.forEach(line -> {
if (line.charAt(24) != 'D') return;
String date = line.substring(10, 18);
long amount = Long.parseLong(line.substring(25, 37).trim());
byDate.merge(date, amount, Long::sum);
});
}
Path out = Path.of("data/daily_deposit.txt");
try (BufferedWriter w = Files.newBufferedWriter(out, StandardCharsets.US_ASCII)) {
for (Map.Entry<String, Long> e : byDate.entrySet()) {
w.write(String.format("%8s%015d", e.getKey(), e.getValue())); // 8 + 15 = 23
w.newLine();
}
}
// 검증
try (Stream<String> lines = Files.lines(out, StandardCharsets.US_ASCII)) {
long bad = lines.filter(l -> l.length() != 23).count();
System.out.println("길이 불일치 줄 수: " + bad);
}
System.out.println(byDate.size() + "일치 기록 -> " + out);
// 출력:
// 길이 불일치 줄 수: 0
// 28일치 기록 -> data\daily_deposit.txt
// 파일 내용 예: 20260901000000002345000