使用Files.readAllLines读取PDF转出文本时出现MalformedInputException异常如何解决
问题排查与修复方案
错误原因
- 编码不匹配:你代码中使用
FileWriter、FileReader读写文件时,默认采用当前操作系统的原生编码(Windows环境通常为GBK),但PDFTextStripper提取的PDF文本多为UTF-8编码,包含的特殊字符(如货币符号、特殊格式分隔符)无法被GBK正确编码存储,后续Files.readAllLines默认以UTF-8读取编码错误的文件内容时,就会抛出MalformedInputException: Input length = 1异常。 - 逻辑冗余错误:你已经通过
LineNumberReader逐行读取文件,找到匹配交易行后不需要重复调用Files.readAllLines读取整个文件,且当前报错行写的.get(0)是取文件第一行,完全不符合你要取匹配行后第4行金额的需求。
修复方案
统一所有文件读写的编码为UTF-8,同时优化行读取逻辑,避免重复IO操作,修复后的代码如下:
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.text.PDFTextStripper; import java.io.*; import java.nio.charset.StandardCharsets; public class BankStatementExtract { public static void main(String[] args) throws IOException { File file = new File("C:\\Users\\wmsai\\Desktop\\BankStatement.pdf"); PDFTextStripper stripper = new PDFTextStripper(); // 写文件时显式指定UTF-8编码 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("bankData"), StandardCharsets.UTF_8)); String pdfText = stripper.getText(PDDocument.load(file)).toUpperCase(); bw.write(pdfText); bw.flush(); bw.close(); // 读文件时显式指定UTF-8编码 LineNumberReader lineNum = new LineNumberReader(new InputStreamReader(new FileInputStream("bankData"), StandardCharsets.UTF_8)); String aspenHomeImpro = "PAYMENT: ACH: ASPEN HOME IMPRO"; String line; while ((line = lineNum.readLine()) != null) { if (line.contains(aspenHomeImpro)) { // 找到匹配行后,继续往下读4行拿到金额行,无需重复读取整个文件 String targetLine = null; for (int i = 0; i < 4; i++) { targetLine = lineNum.readLine(); } // 输出金额行内容,此处可自行加逻辑提取金额数值 System.out.println("对应金额行内容:" + targetLine); break; } } lineNum.close(); } }
如果确实需要用Files.readAllLines的方式读取,也需要显式传入UTF-8编码参数:String aspenData = Files.readAllLines(Paths.get("bankData"), StandardCharsets.UTF_8).get(你需要的行索引);
内容的提问来源于stack exchange,提问作者Wyatt
相关产品推荐
相关产品推荐

