BeanIO如何在定长文件读取时过滤@Group注解的Document实体(仅保留RH中documentCode为BB的记录)
解决方案:过滤定长文件解析后的Document实体
根据你的需求,我们可以通过两种方式实现目标:解析后直接过滤(简单易实现,适合中小文件)或解析过程中实时过滤(内存友好,适合大文件)。下面分别给出具体实现:
1. 解析后过滤(推荐优先尝试)
如果你的文件大小适中,先把所有Document解析到内存中,再用Java Stream过滤符合条件的实体,代码清晰且容易维护:
// 假设你已经完成了定长文件的解析,得到了所有Document的列表 List<Document> allDocuments = yourParser.parse(yourFixedLengthFile); // 过滤出符合要求的Document List<Document> filteredDocuments = allDocuments.stream() .filter(document -> { RH recordHeader = document.getRecordHeader(); // 两个条件:documentCode必须是"BB",同时排除特定的RH20210607AA对应的Document return "BB".equals(recordHeader.getDocumentCode()) && !(recordHeader.getDocumentDate().equals(LocalDate.of(2021, 6, 7)) && "AA".equals(recordHeader.getDocumentCode())); }) .collect(Collectors.toList());
逻辑说明:
- 第一个判断
"BB".equals(recordHeader.getDocumentCode())确保只保留documentCode为"BB"的Document; - 第二个判断
!(...)专门排除那个RH20210607AA对应的Document(即documentDate为2021-06-07且documentCode为"AA"的记录)。
2. 解析过程中实时过滤(适合大文件)
如果你的文件非常大,一次性加载到内存会占用过多资源,可以在解析过程中直接判断是否保留当前Document,避免无用对象占用内存。具体实现取决于你使用的定长解析框架,下面是通用的回调式示例:
List<Document> filteredDocuments = new ArrayList<>(); // 假设你的解析器支持回调处理,每解析完一个Document就触发handleDocument方法 yourParser.parse(yourFixedLengthFile, new DocumentCallback() { @Override public void handleDocument(Document document) { RH recordHeader = document.getRecordHeader(); // 应用相同的过滤条件 if ("BB".equals(recordHeader.getDocumentCode()) && !(recordHeader.getDocumentDate().equals(LocalDate.of(2021, 6, 7)) && "AA".equals(recordHeader.getDocumentCode()))) { filteredDocuments.add(document); } } });
额外注意事项
- 确保你的解析框架配置了忽略未知记录:你的文件中有
fake、Unknown record这类无效行,需要开启框架的跳过未知记录功能(比如某些框架的setSkipUnknownRecords(true)配置),避免解析报错; - 验证
RH类的注解正确性:你的RH类中documentCode字段的ordinal=2、length=2配置符合定长规则,确保RH20210607AA会被正确解析为documentCode="AA",RH20210607BB解析为documentCode="BB"。
内容的提问来源于stack exchange,提问作者Giulio Buz
相关产品推荐
相关产品推荐

