Java实现.dat文件转.txt及代码运行无输出问题排查
问题排查结论
程序构建成功但无控制台输出、不生成目标文件,核心原因是代码存在逻辑错误、IO流使用错误、业务逻辑不匹配需求三类问题:运行时读取文件时因不存在终止符@直接触发EOF异常,被粒度极粗的catch块捕获后输出了完全不相关的错误提示,且流资源未正常关闭导致缓冲区数据无法落盘,最终看不到有效输出也生成不了目标文件。
现存代码错误明细
Book类错误
- setter方法写法完全不符合规范:
setYear()、setTitle()没有定义入参,也没有实现给成员变量赋值的逻辑,无法正常修改对象属性。 - 未满足对象序列化要求:如果需要将Book对象直接存入文件、从文件读取对象,必须实现
Serializable接口,现有代码缺失该实现。
FindOldest类错误
- 无效冗余代码过多:静态成员变量
year默认值为0、title默认值为null,初始化的Book test对象没有任何实际作用;导入的Properties、Set、Scanner类完全没有被使用。 - 文件读取逻辑和文件格式完全不匹配:代码实现的是逐字节读取直到遇到
@字符的逻辑,但提供的library.dat是行存储的文本内容,文件内根本不存在@字符,读取到文件末尾会直接抛出EOFException。 - 完全缺失题目要求的核心业务逻辑:没有将读取到的内容封装为Book对象、没有存入长度上限20的数组、没有筛选出版年份小于2000的书籍、没有按要求将符合条件的内容逐行写入目标文件。
- 路径硬编码风险:代码中写死了Windows绝对路径,NetBeans默认运行工作目录为项目根目录,硬编码路径很容易触发权限问题、路径匹配问题导致文件读写失败。
- 异常处理逻辑失效:直接捕获顶层
Exception,没有区分读文件、写文件的不同错误场景,输出的“输入无效值”提示和实际IO错误完全无关,也没有打印异常信息,出问题后无法定位原因。 - 流资源管理不规范:没有使用自动资源关闭机制,一旦运行中抛出异常,流不会被正常关闭,缓冲区的数据不会写入磁盘,直接导致目标文件无法生成。
修正后可运行代码
Book.java
package Question2; import java.io.Serializable; public class Book implements Serializable { private int year; private String title; public Book(int year, String title) { this.year = year; this.title = title; } // 符合规范的getter/setter public int getYear() { return year; } public void setYear(int year) { this.year = year; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }
FindOldest.java
package Question2; import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class FindOldest { public static void main(String[] args) { // 使用相对路径,将library.dat放在项目根目录(和src文件夹同级)即可 File datFile = new File("library.dat"); File targetFile = new File("oldBooks.txt"); List<Book> bookList = new ArrayList<>(); // 读取dat文件,try-with-resources自动关闭流 try (Scanner fileReader = new Scanner(datFile)) { int readCount = 0; // 最多读取20个Book对象 while (fileReader.hasNextLine() && readCount < 20) { String line = fileReader.nextLine().trim(); if (line.isEmpty()) continue; String[] contentParts = line.split(" ", 2); int bookYear = Integer.parseInt(contentParts[0]); String bookTitle = contentParts[1]; bookList.add(new Book(bookYear, bookTitle)); readCount++; } } catch (FileNotFoundException e) { System.out.println("错误:未找到library.dat文件,请检查文件存放路径"); return; } catch (NumberFormatException e) { System.out.println("错误:library.dat文件格式不合法,年份字段不是有效数字"); return; } catch (IOException e) { System.out.println("错误:读取library.dat时发生IO异常:" + e.getMessage()); return; } // 筛选年份小于2000的书籍写入目标文件 try (BufferedWriter fileWriter = new BufferedWriter(new FileWriter(targetFile))) { for (Book book : bookList) { if (book.getYear() < 2000) { fileWriter.write(book.getYear() + " " + book.getTitle()); fileWriter.newLine(); } } System.out.println("处理完成,符合条件的旧书信息已写入oldBooks.txt"); } catch (IOException e) { System.out.println("错误:写入oldBooks.txt时发生IO异常:" + e.getMessage()); } } }
运行注意事项
- 将
library.dat移动到NetBeans项目根目录(和src文件夹同级),不要放在src/Question2路径下,避免路径匹配失败。 - 当前提供的
library.dat中所有书籍年份均为2000及以上,运行后生成的oldBooks.txt为空文件属于正常现象,可以手动添加几条1999年及以前的书籍数据验证筛选逻辑。 - 运行成功后
oldBooks.txt会生成在项目根目录下。
内容的提问来源于stack exchange,提问作者thanabalan tharmalingam
相关产品推荐
相关产品推荐

