Ожидание создания файлов в Java

#java #file #spring-boot

#java #файл #весенняя загрузка

Вопрос:

Я работаю над веб-API (с Spring Boot), который конвертирует pdf с использованием внешнего C api, эта программа работает, но когда я хочу отправить файл в ответе тела, я получаю эту ошибку:

 {
"timestamp": "2019-04-10T09:56:01.696 0000",
"status": 500,
"error": "Internal Server Error",
"message": "file [D:\[Phenix-Monitor]1.pdf] cannot be resolved in the file system for checking its content length",
"path": "/convert/toLinPDf"}
  

Контроллер :

 @PostMapping("/toLinPDf")
public ResponseEntity<ByteArrayResource> convertion(@RequestParam(value = "input", required = false) String in,
        @RequestParam(value = "output", required = false) String out) throws IOException, InterruptedException {
    linearizeService.LinearizePDf(in, out);
    FileSystemResource pdfFile = new FileSystemResource(out);
    return ResponseEntity
            .ok()
            .contentLength(pdfFile.contentLength())
            .contentType(
                    MediaType.parseMediaType("application/pdf"))
            .body(new ByteArrayResource(IOUtils.toByteArray(pdfFile.getInputStream())));

}
  

linearizeService.LinearizePDf(in, out); Я предполагаю, что проблема заключается в том, FileSystemResource pdfFile = new FileSystemResource(out); что в этом методе я использую внешний процесс, поэтому происходит то, что когда я пытаюсь открыть файл с помощью linearizeService, он еще не завершил обработку, поэтому я получаю эту ошибку, мой вопрос: как я могу справиться с этим, я имею в виду, какдождаться создания файла, а затем отправить этот файл?

Комментарии:

1. вам следует попробовать использовать Future API Java 8

2. @HusamBdr, как я могу использовать Future API в моем случае?

3. Пожалуйста, смотрите Ответ ниже

Ответ №1:

Я предлагаю вам использовать Future API Java 8.

Вот обновление для вашего ресурса.

 @PostMapping("/toLinPDf")
public ResponseEntity<ByteArrayResource> convertion(
    @RequestParam(value = "input", required = false) String in,
    @RequestParam(value = "output", required = false) String out) throws IOException, InterruptedException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Callable<String> callable = () -> {
        linearizeService.LinearizePDf(in, out);
        return "Task ended";
};
Future<String> future = executorService.submit(callable);
String result = future.get();
executorService.shutdown();
FileSystemResource pdfFile = new FileSystemResource(out);
return ResponseEntity
            .ok()
            .contentLength(pdfFile.contentLength())
            .contentType(
                    MediaType.parseMediaType("application/pdf"))
            .body(new ByteArrayResource(IOUtils.toByteArray(pdfFile.getInputStream())));

}
  

Комментарии:

1. Этот ответ не отвечает на вопрос. Этот код возвращает немедленно, что linearizeService.LinearizePDf() возвращает, как и код OP. OP заявляет, что LinearizePDf() продолжает выполняться после возврата вызова, и ему нужен совет относительно того, как синхронизировать это поведение. OP не предоставил достаточно информации об API linearizeService() для ответа на вопрос.

2. Я не совсем хорошо вас понял, но я вижу, что он хотел дождаться завершения задачи, а не для синхронизации с ней, есть разница. linearizeService API Очевидно (поскольку он написан на C ), что он использует JNI для запуска фрагмента кода C для создания своего pdf. @Youssef не могли бы вы, пожалуйста, проверить ответ и подтвердить

3. Ваш код функционально идентичен его коду. Он выполняет свой вызов, и когда он возвращается, он читает файл. Вы создаете поток, немедленно блокируете, выполняете вызов в другом потоке, затем считываете файл, когда вызов возвращается. Никакой разницы. Вообще ничего.