Java中使用renameTo方法导致文件数据缺失 您所在的位置:网站首页 文件重命名的时候不见了 Java中使用renameTo方法导致文件数据缺失

Java中使用renameTo方法导致文件数据缺失

2024-07-08 21:42| 来源: 网络整理| 查看: 265

开发的时候发现了es里面数据有缺失,排查了好久,最后怀疑是renameTo方法的时候,在renameTo还没有完成的时候,程序就对生成的文件进行了处理,实际上这个时候文件还没有完全进入目标文件夹

这完全是一个偶发的问题,但是,发生的频率并不算太低,基本上每小时12个点的文件,总会有一个点出现这种情况,我并没有做完全的统计,因为总体数据量比较大。

于是我在renameTo操作后加了一个线程等待一秒钟的操作,就是为了防止出现这种文件还未转移完全的情况

并且我打印了两行日志,看一下被renameTo前后文件是不是有差异

结果果然是,renameTo前后的数据竟然相差相当大

在这里插入图片描述

我研究了一下renameTo的源码,发现最后是调用的native方法

private native boolean rename0(File f1, File f2);

我猜测是rename0方法是在开始执行的时候,发现文件可以移动就返回了true,而此时其实刚开始执行数据移动操作,数据移动还没有完成,理论上这种移动会很快。程序进行操作的文件,13000行的数据,也没有产生问题,为什么2000行的数据会缺失。是不是如果遇到了机器IO极大的时候,可能会影响数据的转移。在转移了部分数据之后,我的程序开始了读操作,然后就出现了不可写入的情况。剩下的数据也就不会再写入了。

但是伴随而来的就是一个问题,rename0方法到底是以什么形式进行转移文件的,未完全转移的时候是否允许对文件进行读写操作。如果允许,那么我猜测可能成立,如果不允许,我的猜测就不成立了。

我开始想调大一点sleep时间,但是每一秒对于上万个文件的处理速度都是很大的影响。我现在发现,我甚至没办法判断rename0是否完成了。

最后处理办法决定通过复制再删除的方法完成试一下,原来的renameTo换成了jdk提供的一个FileChannel的方式实现

try { FileUtil.copyFileUsingFileChannels(backFile,backuppath); backFile.delete(); }catch (Exception e){ LOGGER.error("文件复制失败:"+backPath); }

copyFileUsingFileChannels方法

public static void copyFileUsingFileChannels(File source, File dest) throws IOException { FileChannel inputChannel = null; FileChannel outputChannel = null; try { inputChannel = new FileInputStream(source).getChannel(); outputChannel = new FileOutputStream(dest).getChannel(); outputChannel.transferFrom(inputChannel, 0, inputChannel.size()); } finally { inputChannel.close(); outputChannel.close(); } }

目前观察程序还没有出现缺失数据的情况,待后续观察



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有