JAI 是否过早关闭文件句柄?
Is JAI closing file handles too early?
我正在使用 JAI 读取 java 中的 Tiff 文件。
使用此代码:
RenderedOp renderer = JAI.create("fileload", tifFilename);
return renderer.getAsBufferedImage();
在 java 7 的一个盒子上工作正常,但在其他 java 8 的盒子上工作,得到这个:
Caused by: com.sun.media.jai.codecimpl.util.ImagingException
at com.sun.media.jai.codecimpl.ImagingListenerProxy.errorOccurred(ImagingListenerProxy.java:63)
at com.sun.media.jai.codecimpl.TIFFImage.getTile(TIFFImage.java:1087)
at javax.media.jai.RenderedImageAdapter.getTile(RenderedImageAdapter.java:148)
at javax.media.jai.NullOpImage.computeTile(NullOpImage.java:162)
at com.sun.media.jai.util.SunTileScheduler.scheduleTile(SunTileScheduler.java:904)
at javax.media.jai.OpImage.getTile(OpImage.java:1129)
at javax.media.jai.PlanarImage.copyData(PlanarImage.java:2343)
at javax.media.jai.RenderedImageAdapter.copyData(RenderedImageAdapter.java:163)
at javax.media.jai.RenderedOp.copyData(RenderedOp.java:2299)
at javax.media.jai.PlanarImage.getAsBufferedImage(PlanarImage.java:2525)
at javax.media.jai.PlanarImage.getAsBufferedImage(PlanarImage.java:2546)
at ...
Caused by: com.sun.media.jai.codecimpl.util.ImagingException: IOException occured while reading TIFF image data.
... 17 more
Caused by: java.io.IOException: Stream Closed
at java.io.RandomAccessFile.seek0(Native Method)
at java.io.RandomAccessFile.seek(RandomAccessFile.java:557)
at com.sun.media.jai.codec.FileSeekableStream.read(FileSeekableStream.java:168)
at com.sun.media.jai.codec.SeekableStream.readFully(SeekableStream.java:318)
at com.sun.media.jai.codecimpl.TIFFImage.getTile(TIFFImage.java:1081)
... 16 more
我的理论是,垃圾收集正在启动并完成它不应该完成的事情。很奇怪。将其替换为:
try (SeekableStream seekableStream = new FileSeekableStream(filename)){
TIFFDecodeParam param = null;
ImageDecoder dec = ImageCodec.createImageDecoder("tiff", seekableStream, param);
// convert to buffered image if desired
return new RenderedImageAdapter(dec.decodeAsRenderedImage()).getAsBufferedImage(); // convert to buffered image
}
问题似乎消失了。我的猜测是因为 FileSeekableStream s
没有被过早收集,因为它的句柄保留在局部变量范围内。可能还有其他 JAI 方法可以做到这一点,只需确保在输入流上保留您自己的句柄 [?]
相关(帮助我发现了这个解决方法:RenderedImage to BufferedImage for multipage-tiff reading)
还有JAI create seems to leave file descriptors open
不确定是否也适用于其他图像格式
我正在使用 JAI 读取 java 中的 Tiff 文件。 使用此代码:
RenderedOp renderer = JAI.create("fileload", tifFilename);
return renderer.getAsBufferedImage();
在 java 7 的一个盒子上工作正常,但在其他 java 8 的盒子上工作,得到这个:
Caused by: com.sun.media.jai.codecimpl.util.ImagingException
at com.sun.media.jai.codecimpl.ImagingListenerProxy.errorOccurred(ImagingListenerProxy.java:63)
at com.sun.media.jai.codecimpl.TIFFImage.getTile(TIFFImage.java:1087)
at javax.media.jai.RenderedImageAdapter.getTile(RenderedImageAdapter.java:148)
at javax.media.jai.NullOpImage.computeTile(NullOpImage.java:162)
at com.sun.media.jai.util.SunTileScheduler.scheduleTile(SunTileScheduler.java:904)
at javax.media.jai.OpImage.getTile(OpImage.java:1129)
at javax.media.jai.PlanarImage.copyData(PlanarImage.java:2343)
at javax.media.jai.RenderedImageAdapter.copyData(RenderedImageAdapter.java:163)
at javax.media.jai.RenderedOp.copyData(RenderedOp.java:2299)
at javax.media.jai.PlanarImage.getAsBufferedImage(PlanarImage.java:2525)
at javax.media.jai.PlanarImage.getAsBufferedImage(PlanarImage.java:2546)
at ...
Caused by: com.sun.media.jai.codecimpl.util.ImagingException: IOException occured while reading TIFF image data.
... 17 more
Caused by: java.io.IOException: Stream Closed
at java.io.RandomAccessFile.seek0(Native Method)
at java.io.RandomAccessFile.seek(RandomAccessFile.java:557)
at com.sun.media.jai.codec.FileSeekableStream.read(FileSeekableStream.java:168)
at com.sun.media.jai.codec.SeekableStream.readFully(SeekableStream.java:318)
at com.sun.media.jai.codecimpl.TIFFImage.getTile(TIFFImage.java:1081)
... 16 more
我的理论是,垃圾收集正在启动并完成它不应该完成的事情。很奇怪。将其替换为:
try (SeekableStream seekableStream = new FileSeekableStream(filename)){
TIFFDecodeParam param = null;
ImageDecoder dec = ImageCodec.createImageDecoder("tiff", seekableStream, param);
// convert to buffered image if desired
return new RenderedImageAdapter(dec.decodeAsRenderedImage()).getAsBufferedImage(); // convert to buffered image
}
问题似乎消失了。我的猜测是因为 FileSeekableStream s
没有被过早收集,因为它的句柄保留在局部变量范围内。可能还有其他 JAI 方法可以做到这一点,只需确保在输入流上保留您自己的句柄 [?]
相关(帮助我发现了这个解决方法:RenderedImage to BufferedImage for multipage-tiff reading)
还有JAI create seems to leave file descriptors open
不确定是否也适用于其他图像格式