Выполняет многопоточную загрузку тысяч изображений, вызывая IOException
У меня проблема с загрузкой большого количества изображений через ForkJoinPool, я тестирую на 4-х ядерном Intel с гипер-продвижением так 8 логических потоков. Тем не менее, я ограничиваю пул только 4 потоками. И я получаю ошибки от ImageIO, не в состоянии найти изображение.
public class LoadImages extends RecursiveAction {
private static final long serialVersionUID = 1L;
//this is an example
private static int threadThreshold = totalImages/totalThreads + 2;
private String[] imgArr;
private int arrStart = 0;
private int arrSize = 0;
public LoadImages(String[] imgs, int start, int size) {
imgArr = imgs;
arrSize = size;
arrStart = start;
}
protected void processImages(){
BufferedImage img = null;
for (int i = arrStart; i < arrStart + arrSize; i++) {
try{
img = ImageIO.read(new File(imgArr[i]));
} catch (IOException | CMMException | NullPointerException e) {
System.out.println(imgArr[i]);
e.printStackTrace();
img = null;
}
...
}
}
protected void compute() {
// Check the number of files
if (arrSize <= threadThreshold) {
processImages();
return;
} else {
int split = arrSize / 2;
invokeAll(new LoadImages(imgArr, arrStart, split), new LoadImages(imgArr, arrStart + split, arrSize - split));
}
}
}
Любое понимание того, что я делаю неправильно, было бы замечательно, я замечаю, что оно действительно ломается, только если у меня более 1700 изображений и все изображения имеют размер 5 МБ и более.
Вот ошибка, которую я получаю от Java:
javax.imageio.IIOException: Can't create an ImageInputStream!
at javax.imageio.ImageIO.read(Unknown Source)
Когда я знаю, что файл там. Я использовал этот код в качестве руководства: https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html
3 ответа
Мне кажется, ошибка ImageIO, когда внутренне создает ImageInputStream. Вы пытались читать изображения с помощью ImageInputStream? Подобно:
InputStream is = new FileInputStream("path");
ImageInputStream iis = ImageIO.createImageInputStream(is);
BufferedImage bufImage = ImageIO.read(iis);
Кажется случайным. Я думаю, это может быть просто ошибка оборудования или ОС. Предполагая, что это проблема масштабирования, я советую с вашими 1700+ изображениями, что вам, вероятно, будет лучше настроить это где-нибудь в облаке - это может сэкономить много времени и головных болей
Если вы идете, проверьте источник ImageIO.read(File)
а также ImageIO.read(ImageInputStream)
Вы можете видеть, что видеть, что ImageIO
повторно использует случаи ImageReader
и эта статья говорит, что ImageReader
не является потокобезопасным. Вам, вероятно, придется создать свой собственный ImageReaders
для использования в отдельных темах.
Также вы должны оценить, насколько эта стратегия многопоточности-ввода-вывода действительно приносит вам пользу. Если вы пытаетесь получить данные изображений с вращающегося жесткого диска, ваш процесс, вероятно, будет связан с вводом / выводом, и распараллеливание загрузки не даст вам много.