Создание файлов в отдельном потоке - PullRequest
0 голосов
/ 26 мая 2020

У меня есть метод, который начинает создавать 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 Ответ

3 голосов
/ 26 мая 2020
  1. Ваш код содержит ошибки; вы никогда не сможете использовать этот конструктор FileWriter. Используйте new FileWriter(formatFullFileName, StandardCharsets.UTF_8), который есть только в jdk11. Если вы не используете JDK11, вы вообще не можете использовать FileWriter (он использует кодировку платформы по умолчанию, и это неприемлемо; JSON должен быть в UTF-8 согласно JSON spe c, и у вас нет гарантии, что UTF-8 является вашей платформой по умолчанию).

  2. вы не защищаете свой FileWriter блоком ARM - вы должны добавить это.

  3. В начальном блоке formatFullFileName - это переменная, которая является строкой формата. В методе run () все наоборот (это результат выполнения операции String.format на одном из них). Делает ваш код очень трудным для чтения.

  4. Скорее всего, ваши имена файлов неверны. Вы должны использовать List<Path>, что устранило бы любые сомнения. Если ваш List<String> subFoldersPaths содержит, например, /home/misnomer/project/foo/1stLayerSubFolder0, а константа FILE_NAME (которую вы не добавляли в свои пасты), скажем, example, то путь к самому первому файлу должен быть created становится: /home/misnomer/project/foo/1stLayerSubFolder0example0.json, что не то, что вы хотели - вам не хватает sla sh.

  5. NB: при использовании более нового API пути, запись строки в файл становится намного проще: Files.write(path, string) - это все, что вам нужно (и обратите внимание, что API файлов по умолчанию использует UTF-8, в отличие от большинства других частей java библиотек, которые включают преобразование строк в байты или наоборот).

  6. Для вставки требуется дополнительная информация, или вам следует отладить это самостоятельно: Печать при записи файла, желательно с указанием идентификатора потока (вы можете получить его с помощью Thread.currentThread().getName()). Вот как работает программирование: вы не просто смотрите на это, go - проверь, я не знаю, лучше спросите о переполнении стека! - а затем сдайтесь. Вы его отлаживаете. Используйте отладчик или, если вы не можете / не хотите, используйте отладчик для бедняков: добавьте целую кучу операторов System.out.println. Go через ваш код и представьте (запишите это, если нужно), что делает каждый шаг. Затем добавьте оператор println, подтверждающий это. То самое место, где программа говорит, что она делает, не совпадает с тем, что вы думали о ней? Вот где ошибка. Исправьте это и продолжайте, пока все ошибки не будут устранены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...