提问人:Morinar 提问时间:5/19/2009 最后编辑:Morinar 更新时间:4/15/2013 访问量:8538
使用 ImageIO.read 的 NullPointerException
NullPointerException using ImageIO.read
问:
我在尝试读取图像文件时得到了 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
我不知道发生了什么,特别是因为 File 构造函数正在成功。我似乎找不到任何遇到过类似问题的人。有人有什么想法吗?(Java 5,如果这有什么不同的话)
答:
您是否认为该文件可能只是已损坏,或者 ImageIO 试图将其读取为错误类型的文件?
评论
File 构造函数几乎肯定会成功,无论它是否指向有效/现有文件。至少,我会通过该方法检查您的基础文件是否存在。exists()
评论
在谷歌上搜索 ICOReader 类会得到一个点击:来自 jide-common 的 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 可能是一个问题。
请考虑使用替代方法显式提供格式。
我又仔细研究了一遍,发现您可以指定 ImageReader ImageIO 将使用哪个 ImageReader 并以这种方式读取它。我浏览了我们的代码库,发现我们已经有一个功能可以完全完成我在这里想要完成的事情。对于遇到类似问题的其他人,这里是代码的关键(上面定义了一些废话,但这应该对任何尝试这样做的人有所帮助):
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);
}
感谢您的建议和对大家的帮助。
另请注意,它不是线程安全的(它重用了非线程安全的缓存)。ImageIO.read
ImageReader
这意味着您无法轻松并行读取多个文件。要做到这一点,你必须自己处理。ImageReader
评论