FileAccessor.java
package io.extact.rms.application.persistence.file.io;
import static java.nio.file.StandardOpenOption.*;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import io.extact.rms.application.persistence.file.IoSystemException;
import lombok.Cleanup;
/**
* ファイルアクセスクラス
*/
public class FileAccessor {
/** ファイルパス */
private Path filePath;
// ----------------------------------------------------- constructor methods
/**
* コンストラクタ
* <p>
* @param csvFilePath ファイルパス
*/
public FileAccessor(Path csvFilePath) {
this.filePath = csvFilePath;
}
// ----------------------------------------------------- public methods
/**
* ファイルパスを取得する。
* <p>
* @return ファイルパス
*/
public Path getFilePath() {
return filePath;
}
/**
* ファイルを読み込む。
* <p>
* @param dataList 読み込んだデータを埋めて返す(in/out)
* @return 読み込み件数
* @throws IOException 読み込みエラーが発生した場合
*/
public int load(List<String[]> dataList) throws IOException {
@Cleanup CSVParser parser = CSVParser.parse(filePath, StandardCharsets.UTF_8, CSVFormat.RFC4180);
parser.getRecords().stream()
.map(record -> StreamSupport.stream(record.spliterator(), false).toList())
.map(values -> {
var array = new String[values.size()];
values.toArray(array);
return array;
})
.forEach(dataList::add);
return dataList.size();
}
/**
* ファイルに書き込む。
* <p>
* @param targetData 書き込みデータ
* @throws IOException 読み込みエラーが発生した場合
*/
public void save(String[] targetData) throws IOException {
List<String> singleLine = new ArrayList<>();
singleLine.add(CSVFormat.RFC4180.format((Object[])targetData));
Files.write(filePath, singleLine, StandardCharsets.UTF_8, WRITE, APPEND);
}
/**
* 全件をファイルに書き込む。
* ファイルに既にあるデータは削除される。
*
* @param allData 書き込みデータ
* @throws IOException 読み込みエラーが発生した場合
*/
public void saveAll(List<String[]> allData) throws IOException {
Stream<CharSequence> allLines = allData.stream()
.map(items -> CSVFormat.RFC4180.format((Object[]) items)); // Memory-friendly and lazy stringification
Files.write(filePath, allLines::iterator, StandardCharsets.UTF_8, CREATE, TRUNCATE_EXISTING);
}
/**
* 指定されたリソースファイルを一時ディレクトリにコピーする。
* <p>
* @param resourcePath リソースファイル
* @param resolver コピー先の一時ディレクトリが指定されたPathResolver
* @return 一時ディレクトリにコピーされたファイルのパス
* @throws IOException ファイル入出力エラーが発生した場合
*/
public static Path copyResourceToRealPath(String resourcePath, PathResolver resolver) {
String[] resourcePathNodes = resourcePath.split("/");
String outputFileName = resourcePathNodes[resourcePathNodes.length - 1];
return copyResourceToRealPath(resourcePath, resolver, outputFileName);
}
public static Path copyResourceToRealPath(String resourcePath, PathResolver resolver, String outputFileName) {
try (InputStream in = FileAccessor.class.getResourceAsStream("/" + resourcePath)) {
if (!Files.exists(resolver.getBaseDir())) {
Files.createDirectory(resolver.getBaseDir());
}
var outputFilePath = resolver.resolve(outputFileName);
Files.copy(in, outputFilePath);
return outputFilePath;
} catch (IOException e) {
throw new IoSystemException(e);
}
}
}