Java密码生成器输出密码数量超出预期的问题排查与修复
问题根因
密码数量异常是由两个核心逻辑问题导致的:
- 每次程序运行时没有清空历史
passcode.txt文件,你使用了追加模式(FileWriter第二个参数为true)写入密码,多次运行生成的历史密码都会保留在文件中 - 程序结束时直接读取整个文件的所有内容输出,没有区分本次运行生成的密码和历史残留密码
修复方案
采用「内存存储本次生成密码+启动清空历史文件」的双重保障方案,修改点如下:
- 新增一个
List<String>集合,每次生成密码时同时写入文件和存入集合,最终输出时直接遍历集合,避免读取历史文件内容 - 程序启动时如果
passcode.txt已存在,先清空历史内容,避免旧数据残留 - 优化Scanner实例创建逻辑,避免循环内重复创建资源
修复后完整代码
import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.io.File; import java.io.FileWriter; import java.io.IOException; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); // 存储本次生成的所有密码 List<String> currentPasswords = new ArrayList<>(); try { File file = new File("passcode.txt"); if (!file.exists()) { file.createNewFile(); } else { // 启动时清空旧文件内容 new FileWriter(file, false).close(); } while(true) { System.out.print("\nEnter a password length (6 or more): "); int length = input.nextInt(); if(length < 6) { System.out.println("\n Password length too short. Please try again."); } else { StringBuilder randomPassword = new StringBuilder(); for(int j = 0; j < length; j++) { randomPassword.append(randomCharacter()); } String pwd = randomPassword.toString(); // 存入本次密码集合 currentPasswords.add(pwd); // 写入文件 FileWriter fw = new FileWriter("passcode.txt", true); fw.write(pwd); fw.write("\n"); fw.close(); System.out.println("\nA password has been sent to text file"); System.out.print("Would you like to generate another password? Y/N "); char choice = input.next().charAt(0); if(choice == 'n' || choice == 'N') { System.out.println("\nThank you for using the Pass CodeGenerator.\n"); System.out.println("Here are your randomly generated codes:"); // 直接输出本次生成的密码,不用读文件 for (int i = 0; i < currentPasswords.size(); i++) { System.out.format("%d. %s%n", i+1, currentPasswords.get(i)); } break; } else if(choice == 'y' || choice == 'Y') { continue; } } } input.close(); } catch (IOException e) { System.out.println("An error occurred."); e.printStackTrace(); } } public static char randomCharacter() { int rand = (int)(Math.random()*62); //0-9 数字 10-35 大写字母 36-61 小写字母 if(rand <= 9) { int number = rand + 48; return (char)(number); } else if(rand <= 35) { int uppercase = rand + 55; return (char)(uppercase); } else { int lowercase = rand + 61; return (char)(lowercase); } } }
额外优化点
- 把字符串拼接改为
StringBuilder,避免循环拼接字符串产生的性能损耗 - 新增对大小写Y/N的兼容处理,用户输入大写Y/N也能正常识别
- 把Scanner的创建移到循环外,避免重复创建资源,最后统一关闭
内容的提问来源于stack exchange,提问作者Carly H
相关产品推荐
相关产品推荐

