Java随机字符匹配程序无法写入已存在的TXT文件,求排查
问题排查与修复方案
核心问题分析
你的程序无法写入hey.txt的主要原因有两个:
- FileWriter资源未正确关闭:代码中
writer.close()被注释,且程序通过System.exit(0)直接终止,导致FileWriter的缓冲区数据从未被刷新到磁盘。FileWriter默认使用缓冲区,只有调用flush()或close()时才会将内存中的数据写入文件。 - 不含空格的分支遗漏文件写入逻辑:当输入的目标词汇不含空格时,你只在控制台输出了猜测内容,但没有调用
writer.write()将内容写入文件。
另外还有两个潜在的数组越界隐患:
- 含空格分支中,
alpha数组的长度是27(空格+26个小写字母),但你用了Math.random()*72,会导致数组索引越界抛出异常。 - 不含空格分支中,
alpha1数组的长度是72个字符(26小写+26大写+10数字+10符号),但你用了Math.random()*71,会漏掉最后一个字符。
修复后的代码
import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Scanner; public class RandomWords { public static void main(String[] args) { File file = new File("hey.txt"); if (file.exists()) { System.out.println("The File Exists"); } // 使用try-with-resources自动关闭FileWriter,无需手动调用close() try (FileWriter writer = new FileWriter(file)) { writer.write("go"); Scanner scanner1 = new Scanner(System.in); System.out.println("Enter Words"); String words = scanner1.nextLine(); int letters = words.length(); // 预定义字符数组,避免每次循环重复创建 String[] alpha = " abcdefghijklmnopqrstuvwxyz".split(""); String[] alpha1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*?".split(""); for (int i1 = 1; ; i1++) { if (words.contains(" ")) { StringBuilder sb = new StringBuilder(); for (int i3 = 0; i3 < letters; i3++) { // 使用alpha数组的实际长度计算随机索引,避免越界 sb.append(alpha[(int) (Math.random() * alpha.length)]); } String finall = sb.toString(); System.out.println(finall); writer.write("\n" + finall); writer.flush(); // 实时刷新缓冲区,避免数据堆积 if (finall.equals(words)) { System.out.println("it took " + i1 + " tries to randomly find the word."); double expected = Math.pow(27, letters); System.out.println("It should have taken " + expected + " times, statistically"); System.out.println("The difference between statistically and simulation is " + Math.abs(i1 - expected)); break; // 用break替代System.exit,让try-with-resources自动关闭流 } } else { StringBuilder sb1 = new StringBuilder(); for (int i2 = 0; i2 < letters; i2++) { // 使用alpha1数组的实际长度计算随机索引,避免越界 sb1.append(alpha1[(int) (Math.random() * alpha1.length)]); } String finall1 = sb1.toString(); System.out.println(finall1); writer.write("\n" + finall1); // 补上文件写入逻辑 writer.flush(); // 实时刷新缓冲区 if (finall1.equals(words)) { System.out.println("it took " + i1 + " tries to randomly find the word."); double expected = Math.pow(alpha1.length, letters); // 用实际字符集长度计算期望次数 System.out.println("It should have taken " + expected + " times, statistically"); System.out.println("The difference between statistically and simulation is " + Math.abs(i1 - expected)); break; } } } } catch (IOException e) { e.printStackTrace(); // 捕获并打印IO异常,便于排查问题 } } }
关键修复点说明
- 使用try-with-resources:自动管理FileWriter资源,无论程序正常结束还是异常,都会自动关闭流,确保缓冲区数据写入文件。
- 补上不含空格分支的写入逻辑:添加
writer.write("\n" + finall1)将猜测内容写入文件。 - 修复数组越界问题:用
alpha.length和alpha1.length替代硬编码的72/71,避免索引越界。 - 替换System.exit(0):用
break终止循环,让try-with-resources正常执行关闭操作。 - 添加flush():每次写入后调用
writer.flush(),实时将数据刷入文件,避免长时间运行时内存数据堆积。
内容的提问来源于stack exchange,提问作者Kyotiq
相关产品推荐
相关产品推荐

