【发布时间】:2020-08-01 06:41:28
【问题描述】:
我有一个小型 Java 桌面应用程序,它读取一些图像文件并显示它们。问题是当我想对这些文件执行某些操作(比如说,exiftool 操作)时,它会拒绝,因为 Java 仍在使用它们。
编辑:这仅在 Windows 上发生,您不能在 Java 正在处理(显示)的动画 GIF 文件(转换为 URL 对象)上写入,但在 Ubuntu 上,您可以编辑该文件元数据、系统不认为该文件正在处理中。
这是我的那部分代码。
我读了文件;
ImageInputStream iis = null;
ImageReader reader = null;
iis = ImageIO.createImageInputStream(
f);
Iterator<ImageReader> imageReaders = ImageIO.getImageReaders(iis);
reader = (ImageReader) imageReaders.next();
Path pathe = f.toPath();
String mimeType = Files.probeContentType(pathe);
ImageIcon icon = null;
这是我处理图像、调整大小并制作 JLabel 以查看它们的部分。
我之所以不只是使用 Java ImageIO 用图像填充该标签,ImageIO 只能显示动画 GIF 文件的第一帧。以这种方式将图像转换为 URL 可以使图像保持动画效果(即使在调整大小后)。
ImageIcon icon = null;
Integer labelWidth = this.imageLabel.getWidth();
Integer labelHeight = this.imageLabel.getHeight();
URI img;
img = f.toURI();
URL umg = img.toURL();
icon = new ImageIcon(umg);
//some calculations for setting labelWidth and labelHeight here
icon.setImage(icon.getImage().getScaledInstance(labelWidth, labelHeight,
Image.SCALE_DEFAULT));
最后,流被关闭。
this.imageLabel.setIcon(icon);
iis.close();
reader.dispose();
然后我尝试通过一个进程执行一些 exiftool 命令,它成功读取了图像元数据。但是在更新数据时,如果图像是动画 GIF,它会显示“将临时文件重命名为 C:/Users/path... 时出错”。 如果图像是非动画图像、JPEG、PNG 或 GIF,则不会出现问题,我猜它可以读取和更新元数据。
当我取消图像显示部分代码时,我可以在图像元数据上写入而不会出错。如果我读取 JPEG 文件并显示它,仍然没有问题。如果我读取动画 GIF 并显示它(动画,它是否保持文件连接打开?)不能对此文件进行修改,不能在我的程序或 cmd.exe 上进行,而调试会话未关闭。退出调试后,cmd.exe上的exiftool进程开始正常工作。
关闭 ImageInputStream 或 ImageReader 没有帮助。
有没有办法让Java进程(如果文件是动画的,我使用URI,URL类)在读取操作后释放文件?我提到的这些类是否有释放、关闭、关闭、杀死进程等方法。我需要读取动画图像并显示它们动画并对其进行更新操作。
【问题讨论】:
-
你在windows上吗?那么我认为是windows内部文件访问机制。就像你在outlook中发送一个文件作为附件一样,windows保持访问直到outlook关闭(不管邮件是否发送)
-
我强烈建议使用try-with-resources blocks 来确保关闭/处置物品。
-
嗨@bish,是的,我在 Windows 10 上,在你发表评论后,我尝试在 Ubuntu 上执行我的代码,它没有问题。因此,在 Windows 系统上,如果将 GIF 文件作为 URL 对象读取并显示,Java 会锁定它,但会忽略 JPEG 文件。在 Ubuntu 上,它根本不关心,你可以对正在处理的文件做任何你想做的事情。
标签: java windows swing file url