在 Java 中使用 ExecutorService 和 Callable 写入文件不起作用

Writing a file using ExecutorService and Callable in Java not working

我正在编写一个例程,它将从文件中检索 URL 的列表,使用 JSoup 获取每个 URL 的内容,找到某些模式并将结果写入输出文件(每分析一个 URL 个)。

我有一个 WebPageAnalysisTask(它实现了 Callable),现在它是 returning null,但它将 return 一个保存处理结果的对象(待完成):

public WebPageAnalyzerTask(String targetUrl, Pattern searchPattern) {
    this.targetUrl = targetUrl;
    this.searchPattern = searchPattern;
}

@Override
public WebPageAnalysisTaskResult call() throws Exception {
    long startTime = System.nanoTime();
    String htmlContent = this.getHtmlContentFromUrl();
    List<String> resultContent = this.getAnalysisResults(htmlContent);

    try (BufferedWriter bw = Files.newBufferedWriter(Paths.get("c:/output", UUID.randomUUID().toString() + ".txt"),
            StandardCharsets.UTF_8, StandardOpenOption.WRITE)) {
        bw.write(parseListToLine(resultContent));
    }

    long endTime = System.nanoTime();
    return null;
}

我正在使用 NIO 和 try-with-resources 编写文件。

将使用该任务的代码如下:

/**
 * Starts the analysis of the Web Pages retrieved from the input text file using the provided pattern.
 */
public void startAnalysis() {
    List<String> urlsToBeProcessed = null;

    try (Stream<String> stream = Files.lines(Paths.get(this.inputPath))) {

        urlsToBeProcessed = stream.collect(Collectors.toList());

        if (urlsToBeProcessed != null && urlsToBeProcessed.size() > 0) {
            List<Callable<WebPageAnalysisTaskResult>> pageAnalysisTasks = this
                    .buildPageAnalysisTasksList(urlsToBeProcessed);
            ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
            List<Future<WebPageAnalysisTaskResult>> results = executor.invokeAll(pageAnalysisTasks);
            executor.shutdown();
        } else {
            throw new NoContentToProcessException();
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

/**
 * Builds a list of tasks in which each task will be filled with data required for the analysis processing.
 * @param urlsToBeProcessed The list of URLs to be processed.
 * @return A list of tasks that must be handled by an executor service for asynchronous processing.
 */
private List<Callable<WebPageAnalysisTaskResult>> buildPageAnalysisTasksList(List<String> urlsToBeProcessed) {
    List<Callable<WebPageAnalysisTaskResult>> tasks = new ArrayList<>();
    UrlValidator urlValidator = new UrlValidator(ALLOWED_URL_SCHEMES);

    urlsToBeProcessed.forEach(urlAddress -> {
        if (urlValidator.isValid(urlAddress)) {
            tasks.add(new WebPageAnalyzerTask(urlAddress, this.targetPattern));
        }
    });

    return tasks;
}

包含 URLs 列表的文件正在被读取一次。 ExecutorService 为每个 URL 创建任务,并将异步分析和写入包含结果的文件。

现在正在读取文件,并且正在分析每个 URL 的 HTML 的内容并保存在一个字符串中。但是任务不是写文件。所以我想知道那里会发生什么。

有人可以告诉我是否遗漏了什么吗?

提前致谢。

您可能在以下 try

中遇到异常
try (BufferedWriter bw = Files.newBufferedWriter(Paths.get("c:/output", UUID.randomUUID().toString() + ".txt"),
        StandardCharsets.UTF_8, StandardOpenOption.WRITE)) {
  bw.write(parseListToLine(resultContent));
}

尝试向其添加一个 catch 块并打印异常,如果它确实碰巧看到导致它的原因

catch (IOException e) {
  // Replace with logger or some kind of error handling in production code
  e.printStackTrace();
}

因为任务会运行在classWebPageAnalyzerTask的方法call()处出错,所以你应该检查List<Future<WebPageAnalysisTaskResult>> results = executor.invokeAll(pageAnalysisTasks);的结果并确定当任务 运行ning.

时出现什么错误
    for (Future<WebPageAnalysisTaskResult> future : results ) {
        try {
            future.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }