java移动文件的时候偶尔会提示“另一个程序正在使用此文件,进程无法访问”,是什么原因?

alexteng2015 2019-06-05 10:17:14
使用java.nio.file.Files的Files.move()方法移动文件的时候,有时会提示“另一个程序正在使用此文件,进程无法访问”

下面是详细错误描述:
java.nio.file.FileSystemException: d:\test\test.jpg -> d:\pic\190605101307757.jpg: 另一个程序正在使用此文件,进程无法访问。

at sun.nio.fs.WindowsException.translateToIOException(Unknown Source)
at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
at sun.nio.fs.WindowsFileCopy.move(Unknown Source)
at sun.nio.fs.WindowsFileSystemProvider.move(Unknown Source)
at java.nio.file.Files.move(Unknown Source)
at WatchTest$A.makeWatch(WatchTest.java:144)
at WatchTest.main(WatchTest.java:78)

并不是每次都这样,这个是什么原因?
...全文
4205 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
alexteng2015 2019-06-05
  • 打赏
  • 举报
回复
对,就是这个问题,已经解决了,是个笨办法,监控files.move是否成功返回,不成功则反复执行,直到返回成功,测试了一下没有问题,谢谢大家的回复。
  • 打赏
  • 举报
回复
你这只是一个监控这个文件夹的代码,你是怎么将图片添加到你的这个文件夹呢?如果你将文件添加到你的监控文件夹的程序还在运行,那么那个程序就有可能还占用着文件。
alexteng2015 2019-06-05
  • 打赏
  • 举报
回复
这是主要部分的源码:

File directory = new File("");//设定为当前文件夹
String path=directory.getAbsolutePath();
public String watch(String filepath,String npath) {
//初始化被监控的文件夹
final Path path = Paths.get(filepath);
//创建WatchService实例,WatchService类似于观察者模式中的观察者
try (WatchService service = FileSystems.getDefault().newWatchService()) {
//将path注册到WatchService中
path.register(service, StandardWatchEventKinds.ENTRY_CREATE,StandardWatchEventKinds.ENTRY_MODIFY,StandardWatchEventKinds.ENTRY_DELETE);
while (true) {
//注册监听服务,获取事件的各个属性
//serviec.take()这个方法会一直堵塞,直到某个事件发生。
WatchKey key = service.take();
for (WatchEvent<?> watchEvent : key.pollEvents()) {
final WatchEvent.Kind<?> kind = watchEvent.kind();
//丢失或放弃事件时被触发
if (kind == StandardWatchEventKinds.OVERFLOW) {
continue;
}
//当新的文件夹或者文件出现时
else if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
Path eventPath=(Path)watchEvent.context();
//return "新增文件:"+eventPath;
String oldpath=filepath+"\\"+eventPath;
String newpath=npath+"\\"+eventPath;
oldpath=oldpath.replaceAll("\\\\","\\\\\\\\");
newpath=newpath.replaceAll("\\\\","\\\\\\\\");
System.out.println("新增文件:"+eventPath);

File source = new File(oldpath);
File dest = new File(newpath);
copyFile(source,dest);
}
}
//WatchKey实例通过poll或者take返回后,就不会捕获任何事件
//调用reset()方法就可以将这个WatchKey重新回到watchservice队列,可以重新等待新的事件。
boolean valid = key.reset();
if (!valid) {
break;
}
}
} catch (Exception e) {
System.err.println(e);
}
return "";
}



public void copyFile(File source, File dest) throws IOException {
try{
java.nio.file.Files.move(source.toPath(), dest.toPath());
}catch (Exception e) {
System.err.println(e);
}
}
alexteng2015 2019-06-05
  • 打赏
  • 举报
回复
是这样,我写了监听文件夹的程序,如果有新增图片文件则将新增的文件移动到指定的目录中,我试过用文件流,FileChannel,Files.move这些方法,结果都是一样的,不是每次都报错,只是偶尔,而且跟新增的图片文件本身属性没有关系,同一张图片有时可以成功,有时就会报“另一个程序正在使用此文件,进程无法访问”的错误,实在找不出原因在哪里了,难道跟监听程序有关吗?是使用的WatchService进行监听
oYeWeiYang12345 2021-09-27
  • 举报
回复
@alexteng2015 请问你解决了吗?我也是和你一模一样,遇到这个问题。不是每次报错,是偶尔,折腾了我好几天了,求大哥指点一二。谢谢。
游北亮 2019-06-05
  • 打赏
  • 举报
回复 1
文件读写流,是否及时close了, 比如:
InputStreamReader reader = new InputStreamReader(is, encoding)
reader.close();
或者简单一点,所有的Stream都用try括起来:
try (InputStreamReader reader = new InputStreamReader(is, encoding)) {
            int c;
            while ((c = reader.read()) != -1)
                sb.append((char) c);
        }
十八道胡同 2019-06-05
  • 打赏
  • 举报
回复
或者是360正在扫描你的文件,不让你移动,也可能的。。
qybao 2019-06-05
  • 打赏
  • 举报
回复
新文件还未必上传完毕,你就试图移走,自然就出错了

51,394

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧