java实现文件的复制,移动



import java.io.File;//引入类  
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

//实现文件的简单处理,复制和移动文件、目录等  
public class TextCopyFileAndMove {
    public static void fileMove(String from, String to) throws Exception {// 移动指定文件夹内的全部文件
        try {
            File dir = new File(from);
            File[] files = dir.listFiles();// 将文件或文件夹放入文件集
            if (files == null)// 判断文件集是否为空
                return;
            File moveDir = new File(to);// 创建目标目录
            if (!moveDir.exists()) {// 判断目标目录是否存在
                moveDir.mkdirs();// 不存在则创建
            }
            for (int i = 0; i < files.length; i++) {// 遍历文件集
                if (files[i].isDirectory()) {// 如果是文件夹或目录,则递归调用fileMove方法,直到获得目录下的文件
                    fileMove(files[i].getPath(), to + "\\" + files[i].getName());// 递归移动文件
                    files[i].delete();// 删除文件所在原目录
                }
                File moveFile = new File(moveDir.getPath() + "\\"// 将文件目录放入移动后的目录
                        + files[i].getName());
                if (moveFile.exists()) {// 目标文件夹下存在的话,删除
                    moveFile.delete();
                }
                files[i].renameTo(moveFile);// 移动文件
                System.out.println(files[i] + " 移动成功");
            }
        } catch (Exception e) {
            throw e;
        }
    }

    // 复制目录下的文件(不包括该目录)到指定目录,会连同子目录一起复制过去。
    public static void copyFileFromDir(String toPath, String fromPath) {
        File file = new File(fromPath);
        createFile(toPath, false);// true:创建文件 false创建目录
        if (file.isDirectory()) {// 如果是目录
            copyFileToDir(toPath, listFile(file));
        }
    }

    // 复制目录到指定目录,将目录以及目录下的文件和子目录全部复制到目标目录
    public static void copyDir(String toPath, String fromPath) {
        File targetFile = new File(toPath);// 创建文件
        createFile(targetFile, false);// 创建目录
        File file = new File(fromPath);// 创建文件
        if (targetFile.isDirectory() && file.isDirectory()) {// 如果传入是目录
            copyFileToDir(targetFile.getAbsolutePath() + "/" + file.getName(),
                    listFile(file));// 复制文件到指定目录
        }
    }

    // 复制一组文件到指定目录。targetDir是目标目录,filePath是需要复制的文件路径
    public static void copyFileToDir(String toDir, String[] filePath) {
        if (toDir == null || "".equals(toDir)) {// 目录路径为空
            System.out.println("参数错误,目标路径不能为空");
            return;
        }
        File targetFile = new File(toDir);
        if (!targetFile.exists()) {// 如果指定目录不存在
            targetFile.mkdir();// 新建目录
        } else {
            if (!targetFile.isDirectory()) {// 如果不是目录
                System.out.println("参数错误,目标路径指向的不是一个目录!");
                return;
            }
        }
        for (int i = 0; i < filePath.length; i++) {// 遍历需要复制的文件路径
            File file = new File(filePath[i]);// 创建文件
            if (file.isDirectory()) {// 判断是否是目录
                copyFileToDir(toDir + "/" + file.getName(), listFile(file));// 递归调用方法获得目录下的文件
                System.out.println("复制文件 " + file);
            } else {
                copyFileToDir(toDir, file, "");// 复制文件到指定目录
            }
        }
    }

    public static void copyFileToDir(String toDir, File file, String newName) {// 复制文件到指定目录
        String newFile = "";
        if (newName != null && !"".equals(newName)) {
            newFile = toDir + "/" + newName;
        } else {
            newFile = toDir + "/" + file.getName();
        }
        File tFile = new File(newFile);
        copyFile(tFile, file);// 调用方法复制文件
    }

    public static void copyFile(File toFile, File fromFile) {// 复制文件
        if (toFile.exists()) {// 判断目标目录中文件是否存在
            System.out.println("文件" + toFile.getAbsolutePath() + "已经存在,跳过该文件!");
            return;
        } else {
            createFile(toFile, true);// 创建文件
        }
        System.out.println("复制文件" + fromFile.getAbsolutePath() + "到"
                + toFile.getAbsolutePath());
        try {
            InputStream is = new FileInputStream(fromFile);// 创建文件输入流
            FileOutputStream fos = new FileOutputStream(toFile);// 文件输出流
            byte[] buffer = new byte[1024];// 字节数组
            while (is.read(buffer) != -1) {// 将文件内容写到文件中
                fos.write(buffer);
            }
            is.close();// 输入流关闭
            fos.close();// 输出流关闭
        } catch (FileNotFoundException e) {// 捕获文件不存在异常
            e.printStackTrace();
        } catch (IOException e) {// 捕获异常
            e.printStackTrace();
        }
    }

    public static String[] listFile(File dir) {// 获取文件绝对路径
        String absolutPath = dir.getAbsolutePath();// 声获字符串赋值为路传入文件的路径
        String[] paths = dir.list();// 文件名数组
        String[] files = new String[paths.length];// 声明字符串数组,长度为传入文件的个数
        for (int i = 0; i < paths.length; i++) {// 遍历显示文件绝对路径
            files[i] = absolutPath + "/" + paths[i];
        }
        return files;
    }

    public static void createFile(String path, boolean isFile) {// 创建文件或目录
        createFile(new File(path), isFile);// 调用方法创建新文件或目录
    }

    public static void createFile(File file, boolean isFile) {// 创建文件
        if (!file.exists()) {// 如果文件不存在
            if (!file.getParentFile().exists()) {// 如果文件父目录不存在
                createFile(file.getParentFile(), false);
            } else {// 存在文件父目录
                if (isFile) {// 创建文件
                    try {
                        file.createNewFile();// 创建新文件
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } else {
                    file.mkdir();// 创建目录
                }
            }
        }
    }

    public static void main(String[] args) {// java程序主入口处
        String fromPath = "E:/biaoq";// 目录路径
        String toPath = "E:/test";// 源路径
        System.out.println("1.移动文件:从路径 " + fromPath + " 移动到路径 " + toPath);
        try {
            fileMove(fromPath, toPath);// 调用方法实现文件的移动
        } catch (Exception e) {
            System.out.println("移动文件出现问题" + e.getMessage());
        }
        /*System.out.println("2.复制目录 " + toPath + " 下的文件(不包括该目录)到指定目录" + fromPath
                + " ,会连同子目录一起复制过去。");
        copyFileFromDir(fromPath, toPath);// 调用方法实现目录复制
        System.out.println("3.复制目录 " + fromPath + "到指定目录 " + toPath
                + " ,将目录以及目录下的文件和子目录全部复制到目标目录");
        copyDir(toPath, fromPath);// 调用方法实现目录以用目录下的文件和子目录全部复制
*/    }
}


注:


以前我一直以为File#renameTo(File)方法与OS下面的 move/mv 命令是相同的,可以达到改名、移动文件的目的。不过后来经常发现问题:File#renameTo(File)方法会返回失败(false),文件没有移 动,又查不出原因,再后来干脆弃用该方法,自己实现一个copy方法,问题倒是再也没有出现过。

昨天老板同学又遇到这个问题,File#renameTo(File)方法在windows下面工作的好好的,在linux下偶尔又失灵了。回到 家我扫了一遍JDK中File#renameTo(File)方法的源代码,发现它调用的是一个本地的方法(native method),无法再跟踪下去。网上有人说该方法在window下是正常的,在linux下面是不正常的。这个很难说通,SUN不可能搞出这种平台不一 致的代码出来啊。

后面在SUN的官方论坛上看到有人提到这个问题“works on windows, don't work on linux”,后面有人回复说是“file systems”不一样。究竟怎么不一样呢?还是没有想出来...

后面在一个论坛里面发现了某人关于这个问题的阐述:

引用
In the Unix'esque O/S's you cannot renameTo() across file systems. This behavior is different than the Unix "mv" command. When crossing file systems mv does a copy and delete which is what you'll have to do if this is the case.

The same thing would happen on Windows if you tried to renameTo a different drive, i.e. C: -> D:


终于明白咯。

做个实验:

Java代码   收藏代码
  1. File sourceFile = new File("c:/test.txt");  
  2. File targetFile1 = new File("e:/test.txt");  
  3. File targetFile2 = new File("d:/test.txt");  
  4. System.out.println("source file is exist? " + sourceFile.exists()  
  5.     + ", source file => " + sourceFile);  
  6. System.out.println(targetFile1 + " is exist? " + targetFile1.exists());  
  7. System.out.println("rename to " + targetFile1 + " => "  
  8.     + sourceFile.renameTo(targetFile1));  
  9. System.out.println("source file is exist? " + sourceFile.exists()  
  10.     + ", source file => " + sourceFile);  
  11. System.out.println(targetFile2 + " is exist? " + targetFile2.exists());  
  12. System.out.println("rename to " + targetFile2 + " => "  
  13.     + sourceFile.renameTo(targetFile2));  


结果:

Java代码   收藏代码
  1. source file is exist? true, source file => c:\test.txt  
  2. e:\test.txt is exist? false  
  3. rename to e:\test.txt => false  
  4. source file is exist? true, source file => c:\test.txt  
  5. d:\test.txt is exist? false  
  6. rename to d:\test.txt => true  


注意看结果,从C盘到E盘失败了,从C盘到D盘成功了。因为我的电脑C、D两个盘是NTFS格式的,而E盘是FAT32格式的。所以从C到E就是上面文章所说的"file systems"不一样。从C到D由于同是NTFS分区,所以不存在这个问题,当然就成功了。

果然是不能把File#renameTo(File)当作move方法使用。

可以考虑使用apache组织的commons-io包里面的FileUtils#copyFile(File,File)和 FileUtils#copyFileToDirectory(File,File)方法实现copy的效果。至于删除嘛,我想如果要求不是那么精确,可 以调用File#deleteOnExit()方法,在虚拟机终止的时候,删除掉这个目录或文件。

BTW:File是文件和目录路径名的抽象表示形式,所以有可能是目录,千万小心。

转载于:https://my.oschina.net/ckaifeng/blog/490726

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值