Исключение NullPointerException с использованием ImageIO.читать
-
22-08-2019 - |
Вопрос
Я получаю NPE при попытке чтения в файле изображения, и я ни за что на свете не могу понять, почему.Вот моя реплика:
BufferedImage source = ImageIO.read(new File(imgPath));
imgPath в принципе гарантированно является допустимым, и прямо перед тем, как он попадет сюда, он копирует файл с сервера.Когда он попадает на эту строку, я получаю эту трассировку стека:
Exception in thread "Thread-26" java.lang.NullPointerException
at com.ctreber.aclib.image.ico.ICOReader.getICOEntry(ICOReader.java:120)
at com.ctreber.aclib.image.ico.ICOReader.read(ICOReader.java:89)
at javax.imageio.ImageIO.read(ImageIO.java:1400)
at javax.imageio.ImageIO.read(ImageIO.java:1286)
at PrintServer.resizeImage(PrintServer.java:981) <---My function
<Stack of rest of my application here>
Кроме того, это выбрасывается в мое окно вывода:
Не удается создать ICOFile:Не могу прочитать байты:2
Я понятия не имею, что происходит, тем более что Файловый конструктор работает успешно.Кажется, я не могу найти никого, у кого была бы подобная проблема.У кого-нибудь есть какие-нибудь идеи?(Java 5, если это имеет какое-либо значение)
Решение
Я покопался еще немного и обнаружил, что вы можете указать, какой ImageReader ImageIO будет использовать, и прочитать его таким образом.Я покопался в нашей кодовой базе и обнаружил, что у нас уже есть функция для выполнения ИМЕННО того, чего я пытался достичь здесь.Просто для всех, кто сталкивается с подобной проблемой, вот суть кода (часть дерьма определена выше, но это должно помочь любому, кто пытается это сделать):
File imageFile = new File(filename);
Iterator<ImageReader> imageReaders = ImageIO.getImageReadersByFormatName("jpeg");
if ( imageReaders.hasNext() ) {
imageReader = (ImageReader)imageReaders.next();
stream = ImageIO.createImageInputStream(imageFile);
imageReader.setInput(stream, true);
ImageReadParam param = imageReader.getDefaultReadParam();
curImage = imageReader.read(0, param);
}
Спасибо всем за предложения и помощь.
Другие советы
Файловый конструктор почти наверняка добьется успеха, независимо от того, указывает ли он на действительный / существующий файл.По крайней мере, я бы проверил, существует ли ваш базовый файл через exists()
способ.
Также обратите внимание , что ImageIO.read
не является потокобезопасным (он повторно использует кэшированный ImageReader
которые не являются потокобезопасными).
Это означает, что вы не сможете легко читать несколько файлов параллельно.Чтобы сделать это, вам придется иметь дело с ImageReader
это ты сам.
Рассматривали ли вы, что файл может быть просто поврежден, или что ImageIO пытается прочитать его как файл неправильного типа?
Поиск в Google класса ICOReader приводит к одному попаданию: IconsFactory
От жидкий-распространенный.
Очевидно, у них была та же проблема:
// Using ImageIO approach results in exception like this.
// Exception in thread "main" java.lang.NullPointerException
// at com.ctreber.aclib.image.ico.ICOReader.getICOEntry(ICOReader.java:120)
// at com.ctreber.aclib.image.ico.ICOReader.read(ICOReader.java:89)
// at javax.imageio.ImageIO.read(ImageIO.java:1400)
// at javax.imageio.ImageIO.read(ImageIO.java:1322)
// at com.jidesoft.icons.IconsFactory.b(Unknown Source)
// at com.jidesoft.icons.IconsFactory.a(Unknown Source)
// at com.jidesoft.icons.IconsFactory.getImageIcon(Unknown Source)
// at com.jidesoft.plaf.vsnet.VsnetMetalUtils.initComponentDefaults(Unknown Source)
// private static ImageIcon createImageIconWithException(final Class<?> baseClass, final String file) throws IOException {
// try {
// InputStream resource =
// baseClass.getResourceAsStream(file);
// if (resource == null) {
// throw new IOException("File " + file + " not found");
// }
// BufferedInputStream in =
// new BufferedInputStream(resource);
// return new ImageIcon(ImageIO.read(in));
// }
// catch (IOException ioe) {
// throw ioe;
// }
// }
Что они сделали вместо этого?
private static ImageIcon createImageIconWithException(
final Class<?> baseClass, final String file)
throws IOException {
InputStream resource = baseClass.getResourceAsStream(file);
final byte[][] buffer = new byte[1][];
try {
if (resource == null) {
throw new IOException("File " + file + " not found");
}
BufferedInputStream in = new BufferedInputStream(resource);
ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
buffer[0] = new byte[1024];
int n;
while ((n = in.read(buffer[0])) > 0) {
out.write(buffer[0], 0, n);
}
in.close();
out.flush();
buffer[0] = out.toByteArray();
} catch (IOException ioe) {
throw ioe;
}
if (buffer[0] == null) {
throw new IOException(baseClass.getName() + "/" + file
+ " not found.");
}
if (buffer[0].length == 0) {
throw new IOException("Warning: " + file
+ " is zero-length");
}
return new ImageIcon(Toolkit.getDefaultToolkit().createImage(
buffer[0]));
}
Так что, возможно, вы захотите попробовать тот же подход:считайте необработанные байты и используйте Toolkit
чтобы создать из них образ.
"это формат jpeg, но у него нет расширения jpeg ".
Возможно, это все.
Похоже , что библиотека AC.lib-ICO выбрасывает NPE.Поскольку эта библиотека предназначена для чтения формата файла Microsoft ICO, для нее может возникнуть проблема с JPEG.
Рассмотрите возможность явного предоставления формата с использованием альтернативный метод.