Java AVL树代码无法将输出写入output.txt仍输出到控制台的求助
核心问题定位
你之前的代码虽然初始化了FileWriter对象指向output.txt,但全程没有把打印内容写入这个流,所有输出动作都是调用System.out.print/println——这些方法默认只会把内容输出到控制台,根本不会和你新建的文件产生关联,当然文件不会有内容。加上Java IO流存在缓冲区,就算写了内容,不手动关流的话内容也会留在内存里,不会落到磁盘上。
方案1:最小改动实现全量输出写文件(推荐,零修改原有打印逻辑)
不用调整你写的树遍历、打印的任何代码,只需要在程序启动时把Java的标准输出流重定向到output.txt,所有原来的System.out打印内容会自动写入文件,完全不会因为改打印逻辑引入新bug。
核心改动只需要在main方法最开头加3行代码:
public static void main(String[] args) throws IOException { // 新增:将标准输出重定向到output.txt,文件不存在会自动新建 PrintStream fileOut = new PrintStream(new FileOutputStream("output.txt")); System.setOut(fileOut); // 以下是你原本的全部代码,无需任何修改 Main tree = new Main(); Scanner scanner = new Scanner(new File("input.txt")); while(scanner.hasNextInt()) { int x = scanner.nextInt(); tree.root = tree.insert(tree.root, x); } tree.printLevelOrder(); // 必须显式关闭流,将缓冲区内容写入磁盘 fileOut.close(); }
注意:这种方式会让控制台不再显示任何程序输出,所有内容都会直接写入
output.txt。如果需要同时保留控制台输出,可以提前把原控制台的流对象存起来,写文件的同时再往控制台打印。
方案2:手动写入内容到FileWriter(可灵活控制写哪些内容)
如果你希望只把部分内容写进文件、或者保留控制台输出,就需要主动把打印的内容传入FileWriter,需要调整的核心点:
- 把
FileWriter定义成类的静态成员,让树的打印方法能访问到 - 把原来所有调用
System.out.print/println的位置,替换成调用fw.write()写入对应字符串 - 所有内容写完后必须调用
fw.close()刷新缓冲区
核心修改片段参考:
// 类级别定义FileWriter,方便所有方法访问 static FileWriter fw; // 修改打印层级的方法,把内容写进文件 void printLevelOrder() throws IOException { int h = root.height; int i; for (i=1; i<=h; i++) { printLevel(root, i); // 原来的System.out.println()替换为写文件换行 fw.write(System.lineSeparator()); } } void printLevel (Node root ,int level) throws IOException { if (root == null) return; if (level == 1) { String nodeContent = "( " + root.key + " , " + root.height + ", " + getBalance(root) + ")"; // 原来的System.out.print()替换为写文件 fw.write(nodeContent); // 如果需要同时在控制台显示,加回这一行即可 // System.out.print(nodeContent); } else if (level > 1) { printLevel(root.left, level-1); printLevel(root.right, level-1); } }
main方法调整:
public static void main(String[] args) throws IOException { Main tree = new Main(); Scanner scanner = new Scanner(new File("input.txt")); // 自动新建output.txt,文件不存在直接创建,存在会覆盖原有内容 fw = new FileWriter("output.txt"); while(scanner.hasNextInt()) { int x = scanner.nextInt(); tree.root = tree.insert(tree.root, x); } tree.printLevelOrder(); // 关流刷盘,不然文件可能为空 fw.close(); }
高频踩坑提醒
- 只创建FileWriter/PrintStream对象,不调用
write()方法:就算文件自动生成了,也是空文件 - 不调用流的
close()/flush()方法:IO流的默认缓冲区是8KB左右,内容没到阈值的时候不会自动写到磁盘,程序跑完文件可能是空白或者残缺的 - 找不到生成的
output.txt:如果没写绝对路径,文件默认生成在程序运行的工作目录下,可以在代码里加一句System.out.println(new File("output.txt").getAbsolutePath()),直接打印出文件的实际存储路径 - 用FileWriter时要注意字符编码,默认是系统本地编码,如果后续要写中文内容出现乱码,可以换成
new OutputStreamWriter(new FileOutputStream("output.txt"), StandardCharsets.UTF_8)指定UTF-8编码
内容的提问来源于stack exchange,提问作者jefflovespretzels
相关产品推荐
相关产品推荐

