java.io.File的renameTo方法移动文件失败的解决方案

今天线上发现一个问题,发现一个定时移动文件的业务没有正常执行,结合日志和代码发现,移动文件是使用File类的renameTo方法,但是方法返回的都是false,表示文件移动失败。

出现这个问题我第一反应是不是文件权限的问题,但是和运维研究后发现的确不是权限导致的。既然不是权限的问题,那就看看renameTo的实现吧,查看源码发现该方法最终是通过一个本地方法实现的,看不到咋写的。

网上查了一下renameTo这个方法,发现这个方法确实存在一些问题,就是在不同的文件系统中移动是不会成功的。因为测试环境并未出现这个问题,我就把生产环境和测试环境对比了下,发现测试环境下,文件本身的目录和要移动到的目录是在/home下,而生产环境中,文件本身目录是在/home下,要移动到的目录都是在/data下。于是用df命令查看了一下,发现 /home的文件系统是/dev/sda3,类型是xfs的,/data的文件系统是/dev/sdb1,类型是ext4。

既然是这样那就写个demo在自己的虚拟机上验证一下是不是这个原因导致的。

1.首先找两个文件系统不一样的目录,命令df -T

我们用/tmp 和 /run 作为测试目录。

2.测试代码

import java.io.File;
/**
* 文件移动方法测试
*/
public class FileTest {
  public static void main(String[] args) {
     String filePath="/tmp/test.txt";
     File file = new File(filePath);
     boolean b = file.renameTo(new File("/run/test.txt"));
     System.out.println(b);
 }
}

3.编译运行

javac FileTest.java
java FileTest

运行结果输出false,文件也确实未移动成功

解决方法:

使用apache的commons-io包中的工具类的进行文件移动。

1.测试代码:

import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
/**
* 文件移动方法测试
*/
public class FileTest {
  public static void main(String[] args) {
     String filePath="/tmp/test.txt";
     File file = new File(filePath);
     boolean b = file.renameTo(new File("/run/test.txt"));
     System.out.println(b);
     //使用apache的FileUtils工具
     try {
         FileUtils.moveFile(file,new File("/run/test.txt"));
         System.out.println("success");
     } catch (IOException e) {
         e.printStackTrace();
     }
 }
}

2.编译运行

javac -cp /root/jar/commons-io-2.4.jar FileTest.java
java -cp /root/jar/commons-io-2.4.jar: FileTest

运行结果成功移动文件

3.apache的FileUtils移动文件方法的主要实现如下:

//先使用renameTo方法进行移动
boolean rename = srcFile.renameTo(destFile);
if (!rename) {
 //renameTo移动失败,就复制文件,然后删除原文件
 copyFile( srcFile, destFile );
 if (!srcFile.delete()) {
 FileUtils.deleteQuietly(destFile);
 throw new IOException("Failed to delete original file '" + srcFile +
  "' after copy to '" + destFile + "'");
 }
}

总结:

1、文件移动最好不要使用Java的renameTo方法,而是应该使用apache的commons-io包,当然也可以自己封装类似的方法。

2、renameTo方法移动失败是文件系统不同造成的,补充测试发现不同的文件系统,就算类型相同,移动也会失败。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Java快速批量移动文件的实现方法

    文件移动是计算机资源管理常用的一个操作,这在操作系统中可以通过文件的剪切与复制或鼠标拖动来实现.但是在Java文件的编程实现中,大多是通过复制文件到目的地,再删除所有文件来实现的.这对于小文件来说看不出什么弊端,但是如果移动几个大的文件,则会使操作缓慢并且浪费系统资源.本实例将通过File类的renameTo()方法直接实现文件的快速移动,哪怕是移动几GB的文件也不会需要等待太长时间. 思路分析: 首先是视图层.在这里有个建议,因为在某些控件的事件中,常常会访问其他控件,且控件的事件方法用到的参

  • java file.renameTo返回false的原因及解决方案

    java file.renameTo返回false原因 需要对文件夹下的文件重命名,发现返回false了,先用main方法测试,发现没问题,如下 public static void main(String[] args) throws IOException { File file1 = new File("D:\\aabb.xml"); File file2 = new File("D:\\ccdd.xml"); boolean b = file1.rename

  • 文件路径正确,报java.io.FileNotFoundException异常的原因及解决办法

    新添加个发文类型 insert into mis.zyb_sf_type values('121','榆财法字','榆财法字',2,'0','1',21,NULL,'0','发文模板.doc','') 创建文章时出错了, 异常信息: 文件保存失败 Java.io.FileNotFoundException: E:\tomcat\jinzhongshi\jinzs_yuci\webapps\myDoJZS\word\template_fw\发文模版.doc (系统找不到指定的文件.) at jav

  • java IO 文件操作方法总结

    java IO 文件操作方法总结 对于输入输出的理解: 输入输出,以程序为参考点,外部数据进入程序,通过输入流完成.程序将数据给外部设备,通过输出流完成. 文件Io的操作 //获取文件 File file=new File("d:/a.txt"); file.getName()--String//文件名 file.getPath()--String//路径 file.getAbsolutePath()--String//全路径 file.getParent()--String//所在文

  • java文件的重命名与移动操作实例代码

    文件的重命名与移动操作 有时候为了对文件进行统一访问与管理,需要把文件进行重命名,并移动到新的文件夹,如何实现呢? 一枚简单的java小程序即可实现: part_1:需求:我需要把<(E:\BaiduYun\传智播客_张孝祥_Java多线程与并发库高级应用视频教程下载)>文件夹下的所有子文件夹下的视频文件重命名,并移动到新的位置<(E:\BaiduYun\张孝祥_Java多线程与并发库)>; part_2:目录结构如下: E:\BaiduYun E:\BaiduYun\传智播客_张

  • java.io.File的renameTo方法移动文件失败的解决方案

    今天线上发现一个问题,发现一个定时移动文件的业务没有正常执行,结合日志和代码发现,移动文件是使用File类的renameTo方法,但是方法返回的都是false,表示文件移动失败. 出现这个问题我第一反应是不是文件权限的问题,但是和运维研究后发现的确不是权限导致的.既然不是权限的问题,那就看看renameTo的实现吧,查看源码发现该方法最终是通过一个本地方法实现的,看不到咋写的. 网上查了一下renameTo这个方法,发现这个方法确实存在一些问题,就是在不同的文件系统中移动是不会成功的.因为测试环

  • Java Io File文件操作基础教程

    目录 File 类概述 File对象文件操作 File静态方法 获取各种路径 路径整合 获取classpath路径 (常用) 获取Tomcat的bin目录 常用功能 创建目录 创建文件 判断文件或文件夹是否存在 判断是文件还是文件夹 判断是否是绝对路径 判断是否是隐藏文件 删除文件或者整个文件夹 File 类概述 Java IO API中的FIle类可以让你访问底层文件系统,通过File类,你可以做到以下几点: 检测文件是否存在 读取文件长度 重命名或移动文件 删除文件 检测某个路径是文件还是目

  • Java使用File类遍历目录及文件实例代码

    1. 构造函数 File(String args0)//使用一个表示文件或目录的路径的字符串创建一个File对象 File(URL args0)//使用一个URL对象创建File对象 File(File args0, String args1)//使用一个File对象(一般是目录)和一个文件名字符串创建File对象 File(String args0, String args1)//使用一个目录字符串和一个文件名字符串创建对象 使用File类需要注意两点: 第一,File类用于表示文件或目录的名

  • Java编程实现用hash方法切割文件

    Hash,一般翻译做"散列",也有直接音译为"哈希"的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值.这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来唯一的确定输入值.简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数. 如果有大型数据文件(如每行为url或者ip或者单词等的),以G为单位的,处理的时候需先切分.

  • springboot打成jar后获取classpath下文件失败的解决方案

    springboot打成jar后获取classpath下文件 代码如下: ClassPathResource resource = new ClassPathResource("app.keystore"); File file = resource.getFile(); FileUtils.readLines(file).forEach(System.out::println); 解决方式如下: 1. Spring framework String data = "&quo

  • linux下用renameTo方法修改java web项目中文件夹名称的实例

    经测试,在Linux环境中安装tomcat,然后启动其中的项目,在项目中使用java.io.File.renameTo(File dest)方法可行. 之前在本地运行代码可以修改,然后传到Linux服务器上一直无法实现功能,自己一直在捣鼓,以为是window环境和Linux环境不同的原因导致,后面发现在项目中使用renameTo方法修改文件夹名称不行是因为之前改了java web项目中的js,在js中传入值到后台,后台根据值来修改文件夹名称.由于没清除缓存导致js中的代码没有刷新,所以一直出现错

  • Java IO流对文件File操作

    目录 什么是文件 常用的文件操作 创建文件 获取文件信息 目录的操作和文件删除 什么是文件 文件,对我们并不陌生,文件是保存数据的地方,比如大家经常使用的word文档,txt文件,exce|文件..都是文件.它既可以保存一-张图片也可以保持视频,声音... 文件流 文件在程序中是以流的形式来操作的. 流:数据在数据源(文件)和程序(内存)之间经历的路径. 输入流:数据从数据源(文件)到程序(内存)的路径. 输出流:数据从程序(内存)到数据源(文件)的路径. 可以把上面的流比作人喝水 从杯子里的水

  • java中File类的使用方法

    构造函数 复制代码 代码如下: public class FileDemo {     public static void main(String[] args){         //构造函数File(String pathname)         File f1 =new File("c:\\abc\\1.txt");         //File(String parent,String child)         File f2 =new File("c:\\a

  • 实例讲述Java IO文件复制

    前言:IO流主要分为两大类,分别是字节流与字符流 注意: 1.音频文件.图片.视频(范围广),就用字节流 2.只涉及到文本的,就用字符流 使用字节流复制文本内容(其他文件也可以) 代码如下: import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; im

  • java中File类的构造函数及其方法

    1.IO流(Input Output) IO流技术主要的作用是解决设备与设备之间的数据传输问题,比如:硬盘的数据--读取到-->内存中 内存的数据--读取到-->硬盘中 键盘上的数据--读取到-->内存中 2.IO流技术的运用场景 导出报表.上传大头照.下载.解析xml文件.....等等 (数据保存到硬盘,该数据可以做到永久性保存.数据一般以文件的形式保存到硬盘上.sun使用一个File类来描述文件或者文件夹) 3.File类的构造函数(方法) File(String pathname)

随机推荐