Java8-Function的使用之读取文件
首先,我们需要一个 FileCloseAble 类来处理文件写入操作。
import java.util.ArrayList;
import java.util.function.Consumer;
import java.util.List;
public class FileCloseAble<T> implements AutoCloseable {
private Consumer<List<T>> writer;
private int pageSize;
private List<T> buffer;
public FileCloseAble(Consumer<List<T>> writer, int pageSize) {
this.writer = writer;
this.pageSize = pageSize;
this.buffer = new ArrayList<>(Math.max(1, pageSize));
}
public void add(T element) {
buffer.add(element);
if (buffer.size() >= pageSize) {
flush();
}
}
private void flush() {
if (!buffer.isEmpty()) {
writer.accept(new ArrayList<>(buffer));
buffer.clear();
}
}
@Override
public void close() {
flush();
}
}
FileContext 类来存储文件的上下文信息。
public class FileContext {
private File file;
private Charset charset;
private int skipHeader;
private String batchDate;
private int pageSize;
private boolean deleteFlag;
private String filterLineHeader;
// 构造函数、getter 和 setter 省略
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public Charset getCharset() {
return charset;
}
public void setCharset(Charset charset) {
this.charset = charset;
}
public int getSkipHeader() {
return skipHeader;
}
public void setSkipHeader(int skipHeader) {
this.skipHeader = skipHeader;
}
public String getBatchDate() {
return batchDate;
}
public void setBatchDate(String batchDate) {
this.batchDate = batchDate;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public boolean isDeleteFlag() {
return deleteFlag;
}
public void setDeleteFlag(boolean deleteFlag) {
this.deleteFlag = deleteFlag;
}
public String getFilterLineHeader() {
return filterLineHeader;
}
public void setFilterLineHeader(String filterLineHeader) {
this.filterLineHeader = filterLineHeader;
}
}
FileHandler 类
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.stream.Stream;
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Slf4j
public class FileHandler<T, R> {
private FileContext context;
private BiFunction<String, String, T> reader; // 读逻辑
private Consumer<List<T>> writer;// 写逻辑
private LineFilter lineFilter; // 新增过滤逻辑
public void execute() throws Exception {
File file = context.getFile();
try (
Stream<String> streams = Files.lines(Paths.get(file.getPath()), context.getCharset());
FileCloseAble<T> files = new FileCloseAble<>(writer, context.getPageSize())
) {
streams.skip(context.getSkipHeader())
.filter(lineFilter.getLinePredicate())
.map(e -> reader.apply(e, context.getBatchDate()))
.forEach(files::add);
} catch (Exception e) {
log.error("解析文件失败: file: {}, error: {}", file, e);
throw new Exception("文件处理异常", e);
} finally {
deleteFileIfNecessary(file);
}
}
private void deleteFileIfNecessary(File file) {
if (context.isDeleteFlag() && file.exists()) {
try {
boolean deleted = Files.deleteIfExists(file.toPath());
if (deleted) {
log.info("文件已删除: {}", file);
} else {
log.info("文件不存在,无法删除: {}", file);
}
} catch (Exception e) {
log.error("删除文件失败: file: {}, error: {}", file, e);
}
}
}
}
定义一个过滤函数接口
定义一个 Predicate 接口,用于表示每一行的过滤逻辑。
import java.util.function.Predicate;
public interface LineFilter {
Predicate<String> getLinePredicate();
}
实现 LineFilter 接口
创建一个实现了 LineFilter 接口的类,用于定义具体的过滤逻辑。
import java.util.function.Predicate;
public class CustomLineFilter implements LineFilter {
private String filterLineHeader;
public CustomLineFilter(String filterLineHeader) {
this.filterLineHeader = filterLineHeader;
}
@Override
public Predicate<String> getLinePredicate() {
return line -> !line.startsWith(filterLineHeader);
}
}
使用 FileHandler 类
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Consumer;
public class FileHandlerExample {
public static void main(String[] args) {
// 创建文件上下文
FileContext context = new FileContext();
File file = new File("D:\\temp\\testwrite.txt");
context.setFile(file);
context.setCharset(StandardCharsets.UTF_8);
context.setSkipHeader(0);
context.setBatchDate("20220101");
context.setPageSize(100);
context.setDeleteFlag(false);
// 定义解析方法
BiFunction<String, String, String> reader = (line, batchDate) -> line.trim();
// 定义写入方法
Consumer<List<String>> writer = list -> {
for (String s : list) {
System.out.println(s);
}
};
// 创建自定义过滤逻辑
LineFilter lineFilter = new CustomLineFilter("#");
// 创建 FileHandler 实例
FileHandler<String, Void> fileHandler = FileHandler.<String, Void>builder()
.context(context)
.reader(reader)
.writer(writer)
.lineFilter(lineFilter) // 设置过滤逻辑
.build();
// 执行文件处理
try {
fileHandler.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
}
可以愉快的读写文件啦