23

总结java中文件拷贝剪切的5种方式-JAVA IO基础总结第五篇

 3 years ago
source link: http://www.cnblogs.com/zimug/p/13599866.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

aERBjqA.png!mobile 本文是Java IO总结系列篇的第5篇,前篇的访问地址如下:

很多朋友在看我的《java IO总结系列》之前觉得创建文件、文件夹删除文件这些基础操作真的是太简单了。但看了我的文章之后,有小伙伴找到我说:“没想到这么基础的知识里面还有这么多的门门道道,用起来很容易,真的用好也不容易”。哪一个方法用起来简单,哪一个方法在异常处理方面更加健壮,不看我的总结你可能还真的不知道。

有兴趣的了解更多的小伙伴可以关注我,我会持续的写这一系列的文章。如果您觉得我的文章对您有帮助,请帮忙点个赞,您的支持是我不竭的创作动力!

那我们下面就来为大家介绍本篇的内容: 文件拷贝(重命名)与剪切的5种方法 。首先我们来理解以下下面的几个概念:

  • 文件拷贝:将文件从一个文件夹复制到另一个文件夹
  • 文件剪切:将文件从当前文件夹,移动到另一个文件夹
  • 文件重命名:将文件在当前文件夹下面改名(也可以理解为将文件剪切为当前文件夹下面的另一个文件)

一、文件拷贝

传统IO中的文件copy的方法,使用输入输出流,实际上就是重新创建并写入一个文件。如果目标文件已经存在,就覆盖掉它,重新创建一个文件并写入数据。这种方式不够友好, 覆盖掉原有文件没有给出任何提示,有可能导致原有数据的丢失

@Test
void testCopyFile1() throws IOException {
  File fromFile = new File("D:\\data\\test\\newFile.txt");
  File toFile = new File("D:\\data\\test2\\copyedFile.txt");

  try(InputStream inStream = new FileInputStream(fromFile);
      OutputStream outStream = new FileOutputStream(toFile);) {

    byte[] buffer = new byte[1024];

    int length;
    while ((length = inStream.read(buffer)) > 0) {
      outStream.write(buffer, 0, length);
      outStream.flush();
    }

  }
}

Java NIO中文件copy的方法,使用方式简单。当目标文件已经存在的时候会抛出FileAlreadyExistsException ,当源文件不存在的时候抛出NoSuchFileException,针对不同的异常场景给出不同的Exception,更有利于我们写出健壮性更好的程序。

@Test
void testCopyFile2() throws IOException {
  Path fromFile = Paths.get("D:\\data\\test\\newFile.txt");
  Path toFile = Paths.get("D:\\data\\test2\\copyedFile.txt");

  Files.copy(fromFile, toFile);
}

如果在目标文件已经存在的情况下,你不想抛出FileAlreadyExistsException ,而是去覆盖它,也可以灵活的选择使用下面的选项

  • StandardCopyOption.REPLACE_EXISTING 来忽略文件已经存在的异常,如果存在就去覆盖掉它
//如果目标文件存在就替换它
Files.copy(fromFile, toFile, StandardCopyOption.REPLACE_EXISTING);
  • StandardCopyOption.COPY_ATTRIBUTES copy文件的属性,最近修改时间,最近访问时间等信息,不仅copy文件的内容,连文件附带的属性一并复制
CopyOption[] options = { StandardCopyOption.REPLACE_EXISTING,
      StandardCopyOption.COPY_ATTRIBUTES //copy文件的属性,最近修改时间,最近访问时间等
};
Files.copy(fromFile, toFile, options);

二、文件重命名

NIO中可以使用Files.move方法在同一个文件夹内移动文件,并更换名字。当目标文件已经存在的时候,同样会有FileAlreadyExistsException,也同样可以使用StandardCopyOption去处理该异常。

@Test
void testRenameFile() throws IOException {
  Path source = Paths.get("D:\\data\\test\\newFile.txt");
  Path target = Paths.get("D:\\data\\test\\renameFile.txt");

  //REPLACE_EXISTING文件存在就替换它
  Files.move(source, target,StandardCopyOption.REPLACE_EXISTING);
}

下文中的实现方法和上面代码的效果是一样的,resolveSibling作用是将source文件的父路径与参数文件名合并为一个新的文件路径。

resolve系列函数在windows和linux等各种系统处理路径分隔符号、路径与文件名合并等,比自己手写代码去处理不同操作系统的路径分隔符号、路径与文件名合并有更好的操作系统兼容性。

@Test
void testRenameFile2() throws IOException {
  Path source = Paths.get("D:\\data\\test\\newFile.txt");

  //这种写法就更加简单,兼容性更好
  Files.move(source, source.resolveSibling("renameFile.txt"));
}

传统IO中使用File类的renameTo方法重命名,失败了就返回false,没有任何异常抛出。你不会知道你失败的原因是什么,是因为源文件不存在导致失败?还是因为目标文件已经存在导致失败?所以这种方法笔者不建议使用。

@Test
void testRenameFile3() throws IOException {

  File source = new File("D:\\data\\test\\newFile.txt");
  boolean succeeded = source.renameTo(new File("D:\\data\\test\\renameFile.txt"));
  System.out.println(succeeded);  //失败了false,没有异常
}

三、文件剪切

文件剪切实际上仍然是Files.move,如果move的目标文件夹不存在或源文件不存在,都会抛出NoSuchFileException

@Test
void testMoveFile() throws IOException {

  Path fromFile = Paths.get("D:\\data\\test\\newFile.txt"); //文件
  Path anotherDir = Paths.get("D:\\data\\test\\anotherDir"); //目标文件夹

  Files.createDirectories(anotherDir);
  Files.move(fromFile, anotherDir.resolve(fromFile.getFileName()),
          StandardCopyOption.REPLACE_EXISTING);
}

resolve函数是解析anotherDir路径与参数文件名进行合并为一个新的文件路径。

欢迎关注我的博客,里面有很多精品合集

  • 本文转载注明出处(必须带连接,不能只转文字): 字母哥博客

觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力!。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK