Java使用Process类打开PNG/JPG图片时进程立即退出问题求解
问题根因
- 该问题确实由Windows Photos查看器的运行机制导致。PDF、TXT、DOCX对应的默认打开程序(Office、记事本、PDF阅读器等)通常会为每个打开的文件启动独立的前台进程,进程会在用户关闭文件后退出,因此
waitFor()可以正常等待到进程结束。 - Windows Photos属于UWP应用,采用单实例多窗口的运行逻辑:你通过cmd调用打开图片时,系统会先启动一个临时转发进程,该进程把打开请求传递给后台已经驻留的Photos主进程后就会立刻退出,因此你代码中的
waitFor()会直接返回,不等用户关闭图片窗口就执行了删除逻辑。 - 你之前加
Thread.sleep()的方案无效,是因为临时进程退出后,是后台的Photos主进程在占用图片文件,sleep时间到后不管图片是否打开都会执行删除,自然不符合需求。
解决方案
优先推荐文件锁检测方案,不依赖用户的默认打开程序设置,兼容性最强:
@Override public void run() { try { // 启动程序打开目标文件 Process openProcess = new ProcessBuilder("cmd.exe", "/C", path).start(); openProcess.waitFor(); File targetFile = new File(path); // 循环检测文件占用状态 while (targetFile.exists()) { // 尝试获取文件独占锁,拿到锁说明无其他进程占用 try (RandomAccessFile raf = new RandomAccessFile(targetFile, "rw"); FileChannel fileChannel = raf.getChannel()) { FileLock lock = fileChannel.tryLock(); if (lock != null) { lock.release(); // 无占用,执行删除 Files.delete(targetFile.toPath()); break; } } catch (IOException e) { // 捕获到锁获取异常说明文件被占用,等待1秒后重试 Thread.sleep(1000); } } } catch (IOException | InterruptedException e) { e.printStackTrace(); // 中断异常要恢复中断状态 if (e instanceof InterruptedException) { Thread.currentThread().interrupt(); } } }
该方案每秒检测一次文件占用状态,资源消耗极低,适配所有类型的文件和任意默认打开程序。
内容的提问来源于stack exchange,提问作者Aleksandar Cvisic
相关产品推荐
相关产品推荐

