По сути, я пытаюсь преобразовать файл tiff в pdf, используя itext, что довольно просто. Но из того, что я вижу, TiffImage.getTiffImage
требуется много времени для выполнения больших файлов.
Мое требование состоит в том, чтобы использовать FutureTask
и ExecutorService
для предоставления многопоточного решения. Вот мой текущий код:
import java.util.concurrent.Callable;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.RandomAccessFileOrArray;
import com.itextpdf.text.pdf.codec.TiffImage;
public class ProcessTiffImage implements Callable<Image>{
RandomAccessFileOrArray tiffFile;
int pageNo;
public ProcessTiffImage(RandomAccessFileOrArray tiffFile, int pageNo){
this.tiffFile = tiffFile;
this.pageNo = pageNo;
}
public Image call() throws Exception {
Image image = TiffImage.getTiffImage(tiffFile, pageNo);
return image;
}
}
и метод преобразования
public boolean convert(Document document) {
int numOfThreads = Runtime.getRuntime().availableProcessors() ;
ExecutorService service = Executors.newFixedThreadPool(numOfThreads );
List<FutureTask<Image>> taskList = new ArrayList<FutureTask<Image>>();
List<Image> imageList = new ArrayList<Image>();
for (int page = 1; page <= numOfPages; page++) {
FutureTask<Image> futureTask = new FutureTask<Image>(new ProcessTiffImage(tiffFile, page));
taskList.add(futureTask);
service.execute(futureTask);
}
try {
// Wait until all results are available
for (FutureTask<Image> future : taskList) {
imageList.add(future.get());
}
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (ExecutionException ex) {
ex.printStackTrace();
}
service.shutdown();
boolean success = generatePdf(document, imageList);
return success;
}
Но я получаю NullPointerException
в future.get()
. Проблема в том, что выполнение не ожидает завершения TiffImage.getTiffImage(tiffFile, pageNo). Следовательно, я не могу создать список изображений. Любая помощь будет очень высоко ценится.
Трассировки стека
java.util.concurrent.ExecutionException: java.lang.NullPointerException
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:188)
at com.app.convertor.TiffParser.convert(TiffParser.java:107)
at com.app.start.TiffToPdf.main(TiffToPdf.java:40)
Caused by: java.lang.NullPointerException
Caused by: java.lang.NullPointerException
at com.itextpdf.text.pdf.codec.TIFFDirectory.getFieldAsLong(TIFFDirectory.java:467)
at com.itextpdf.text.pdf.codec.TIFFDirectory.getFieldAsLong(TIFFDirectory.java:477)
at com.itextpdf.text.pdf.codec.TiffImage.getTiffImage(TiffImage.java:124)
at com.itextpdf.text.pdf.codec.TiffImage.getTiffImage(TiffImage.java:106)
at com.app.processor.ProcessTiffImage.call(ProcessTiffImage.java:20)
at com.app.processor.ProcessTiffImage.call(ProcessTiffImage.java:1)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
RandomAccessFileOrArray
не является потокобезопасным. Смотрите мой ответ ниже. - person chiastic-security   schedule 20.10.2015