在单独的线程中创建文件

时间:2020-05-26 11:29:15

标签: java multithreading

我有一个方法可以开始在树中的每个文件夹中创建JSON文件。

public static void fill(List<String> subFoldersPaths) {
    for (int i = 0; i < subFoldersPaths.size(); i++) {
        String fullFileName = subFoldersPaths.get(i) + FILE_NAME;
        String formatFullFileName = String.format(fullFileName, i)+"%d";
        Runnable runnable = new JsonCreator(formatFullFileName);
        new Thread(runnable).start();
    }
}

List<String> subFoldersPaths是一个列表,按顺序包含每个文件夹的路径。

这是我的文件夹结构:

folder structure

我希望每个文件夹每0.08秒在一个单独的线程中充满文件。但是我的课不会填满每个文件夹。

这是一个实现Runnable的类,该类应执行填充:

import com.epam.lab.model.Author;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import net.andreinc.mockneat.MockNeat;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.FileWriter;
import java.io.IOException;

public class JsonCreator implements Runnable {
    private static Logger logger = LogManager.getLogger();
    private static String fileName;
    private static final int FILES_COUNT = 100;

    public JsonCreator(String s){
        this.fileName = s;
    }

    @Override
    public void run() {
        for (int i = 0; i < FILES_COUNT; i++) {
            try {
                String formatFullFileName = String.format(fileName, i)+".json";
                FileWriter fileWriter = new FileWriter(formatFullFileName);
                fileWriter.write(createJsonString());
                fileWriter.close();
                Thread.sleep(80);
            } catch (IOException | InterruptedException e) {
                logger.error("File was not created", e);
            }
        }
    }

    private static String createJsonString() {
        MockNeat mockNeat = MockNeat.threadLocal();
        Gson gson = new GsonBuilder()
                .setPrettyPrinting()
                .create();
        String json = mockNeat
                .reflect(Author.class)
                .field("authorName", mockNeat.names().first())
                .field("authorSurname", mockNeat.names().last())
                .map(gson::toJson)
                .val();
        return json;
    }
}

但是该课程的文件不是不是每个文件夹。 (也许文件名有问题)我无法弄清楚。

并且我希望将“ foo”下的每个文件夹填充到JSON文件的单独线程中,其数量为FILES_COUNT = 10

一些算法执行示例:

example1 example2

文件夹结构是在随机的参与下创建的,因此几乎总是不同的。但这不会影响并非在所有文件夹中都创建文件的事实

1 个答案:

答案 0 :(得分:3)

  1. 您的代码有错误;您永远无法使用该FileWriter构造函数。使用仅在jdk11中使用的new FileWriter(formatFullFileName, StandardCharsets.UTF_8)。如果您不在JDK11上,则根本不能使用FileWriter(它使用平台默认编码,这是不可接受的;根据JSON规范,JSON必须使用UTF-8,并且不能保证UTF- 8是您的平台默认设置。)

  2. 您不是用ARM block保护您的FileWriter-您应该添加它。

  3. 在初始块中,formatFullFileName是一个格式字符串变量。在run()方法中,情况恰恰相反(这是对一个String.format运行op的结果)。使您的代码很难阅读。

  4. 您的文件名很可能不正确。您应该使用List<Path>,它将消除任何疑问。例如,如果您的List<String> subFoldersPaths中包含/home/misnomer/project/foo/1stLayerSubFolder0,并且常量FILE_NAME(您未粘贴在其中)为example,则创建第一个文件的路径变为:/home/misnomer/project/foo/1stLayerSubFolder0example0.json,这不是您想要的-您缺少斜杠。

  5. NB:如果使用较新的path API,则将字符串写入文件变得非常简单:Files.write(path, string)就是您所需要的(并且请注意,与其他大多数文件不同,Files API默认为UTF-8) Java库中涉及将字符串转换为字节,反之亦然的部分)。

  6. 粘贴需要更多信息,或者您应该自行调试:写入文件时打印,最好包含线程ID(可以使用Thread.currentThread().getName()获得)。编程就是这样工作的:您不只是盯着它,走-哎呀,我不知道,最好问一下堆栈溢出!-然后放弃。您调试它。使用调试器,或者如果您愿意/不愿意,请使用可怜的调试器:添加一堆System.out.println语句。仔细检查您的代码,然后想象一下(如果需要,请写下来)每个步骤正在执行的操作。然后,添加一个println语句来确认这一点。程序所说的正在执行的位置与您认为的将要执行的位置不匹配?那是一个错误所在。对其进行修复,直到消除所有错误为止。