You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用for循环与PrintWriter生成多份随机命名文件的问题排查

问题分析与解决方案

嘿,我一眼就揪出问题所在啦——你输入大于1的数值后只生成一个文件,核心原因是生成随机文件名和类名的代码被放在了for循环外面,导致整个循环过程中都在复用同一个文件名,每次循环都会覆盖之前创建的文件,最后自然只剩最后一次写入的那个文件咯。

具体问题点

你看这段代码:

String printername = (rangen.getnumlet(length) + ".java");
String name = (printername.substring(0 , printername.indexOf('.')).trim());

这两行是在main方法中、for循环执行前就运行的,只会生成一次随机文件名和类名。后面的for循环每次创建PrintWriter时,都用的是同一个printername,相当于反复往同一个文件里写内容(而且每次创建PrintWriter时会清空文件原有内容),最终就只会留下最后一次写入的文件。

修正后的代码

只需要把生成文件名和类名的代码移到for循环内部,让每次循环都生成新的随机名称就行。另外我还加了几个实用优化:用try-with-resources自动关闭流,避免手动关闭可能出现的资源泄漏;同时把生成的类名首字母转成大写,符合Java类名规范,避免编译错误。

import java.util.Scanner;
import java.io.PrintWriter;
import java.io.FileNotFoundException;

public class rangen {
    static String getnumlet(int n) {
        String numlet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        StringBuilder sb = new StringBuilder(n);
        for (int i = 0 ; i < n ; i++) {
            int index = (int)(numlet.length() * Math.random());
            sb.append(numlet.charAt(index));
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        final int length = 10;
        int amount = 0;
        Scanner input = new Scanner(System.in);

        System.out.print("Enter the amount of files you want to create: ");
        amount = input.nextInt();

        for (int i = 1 ; i <= amount ; i++) {
            // 把生成文件名和类名的代码移到循环内部,每次循环生成新名称
            String printername = (rangen.getnumlet(length) + ".java");
            // 处理类名:首字母大写,符合Java规范
            String rawName = printername.substring(0, printername.indexOf('.')).trim();
            String name = rawName.substring(0, 1).toUpperCase() + rawName.substring(1);
            
            // 使用try-with-resources自动关闭PrintWriter,更安全
            try (PrintWriter tofile = new PrintWriter(printername)) {
                tofile.print("// Creator: Unknown...\n");
                tofile.print("// Date Created: 9-28-2019\n");
                tofile.print("// Last Modified: 9-28-2019\n");
                tofile.print("// Description: This file was \n" + "// randomly generated.\n");
                tofile.print("public class " + name + " {\n");
                tofile.print(" public static void main(String[] args) {\n");
                tofile.print(" private static final double inf = \n" + " Double.POSITIVE_INFINITY;\n");
                tofile.print(" for (int x = 1 ; x <= inf ; x++) {\n"); // 变量名改为x,避免和外部循环的i冲突
                tofile.print(" System.out.print(\"yeet \" + x);\n");
                tofile.print(" }\n");
                tofile.print(" }\n");
                tofile.print("}\n");
                for (int x = 0 ; x <= 5; x++ ) {
                    tofile.print("// LOL " + x + "\n");
                }
                System.out.println("Successfully created: " + printername);
            } catch (FileNotFoundException e) {
                System.out.println("couldn't create " + printername);
            }
            // 无需手动关闭tofile,try-with-resources会自动处理
        }
        input.close();
    }
}

额外说明

  1. 我把内部循环的变量名从i改成了x,避免和外部for循环的i重名,虽然Java语法允许,但这样代码可读性更好。
  2. 新增了成功创建文件的提示,方便你直观确认每个文件都正常生成。
  3. 处理类名首字母大写是因为Java要求类名必须以大写字母开头,否则编译会报错哦。

内容的提问来源于stack exchange,提问作者Chgearft

火山引擎 最新活动