java高效复制文件并移动_Java 7:复制和移动文件和目录

java高效复制文件并移动

这篇文章是我对Java 7 java.nio.file软件包的系列文章的继续,这次涵盖了文件的复制和移动以及完整的目录树。 如果您曾经对Java缺少copy和move方法感到沮丧,那么请继续阅读,以免麻烦。 涵盖范围中包括非常有用的Files.walkFileTree方法。 但是,在我们深入研究主要内容之前,需要一些背景信息。

路径对象
路径对象代表可能包含或不包含文件的目录序列。 有三种方法构造Path对象:

  1. FileSystems.getDefault()。getPath(字符串优先,字符串…更多)
  2. Paths.get(String path,String…更多),调用FileSystems.getDefault()。getPath的便捷方法
  3. 在java.io.File对象上调用toPath方法

从现在开始,在所有示例中,我们将使用Paths.get方法。 以下是创建Path对象的一些示例:

//Path string would be "/foo"
Paths.get("/foo");
//Path string "/foo/bar"
Paths.get("/foo","bar");

要操作Path对象,可以使用Path.resolve和Path.relativize方法。 这是使用Path.resolve的示例:

//This is our base path "/foo"
Path base = Paths.get("/foo");
//filePath is "/foo/bar/file.txt" while base still "/foo"
Path filePath = base.resolve("bar/file.txt");

使用Path.resolve方法会将给定的String或Path对象追加到调用Path的末尾,除非给定的String或Path表示绝对路径,否则将返回给定的路径,例如:

Path path = Paths.get("/foo");
//resolved Path string is "/usr/local"
Path resolved = path.resolve("/usr/local");

Path.relativize以相反的方式工作,返回一个新的相对路径,如果根据调用的Path解析该路径,则会得到相同的Path字符串。 这是一个例子:

// base Path string "/usr"Path base = Paths.get("/usr");// foo Path string "/usr/foo"Path foo = base.resolve("foo");// bar Path string "/usr/foo/bar"Path bar = foo.resolve("bar");// relative Path string "foo/bar"Path relative = base.relativize(bar);

Path类上另一个有用的方法是Path.getFileName,该方法返回此Path对象表示的最远元素的名称,该名称是实际文件或目录。 例如:

//assume filePath constructed elsewhere as "/home/user/info.txt"
//returns Path with path string "info.txt"
filePath.getFileName()//now assume dirPath constructed elsewhere as "/home/user/Downloads"
//returns Path with path string "Downloads"
dirPath.getFileName()

在下一节中,我们将研究如何将Path.resolve和Path.relativize与Files类一起使用来复制和移动文件。

文件类

Files类由使用Path对象处理文件和目录的静态方法组成。 尽管Files类中有50多个方法,但目前我们仅讨论复制和移动方法。

复制文件

要将一个文件复制到另一个文件,您可以使用(对名称的任何猜测?)Files.copy方法–非常简洁(没有路径的内部类)的copy(路径源,Path目标,CopyOption…选项),我们确定它是Java吗? options参数是枚举,用于指定应如何复制文件。 (实际上有两个不同的Enum类,LinkOption和StandardCopyOption,但是都实现CopyOption接口。)这是Files.copy的可用选项列表:

  1. LinkOption.NOFOLLOW_LINKS
  2. StandardCopyOption.COPY_ATTRIBUTES
  3. StandardCopyOption.REPLACE_EXISTING

还有一个StandardCopyOption.ATOMIC_MOVE枚举,但是如果指定了此选项,则抛出UsupportedOperationException。 如果未指定任何选项,则默认为在目标文件存在或为符号链接的情况下引发错误。 如果路径对象是目录,那么将在目标位置中创建一个空目录。 (请稍等!在引言中没有说我们可以复制目录的全部内容吗?答案仍然是肯定的,而且即将到来!)这是使用Path使用Path对象将文件复制到另一个文件的示例.resolve和Path.relativize方法:

Path sourcePath ...Path basePath ...Path targetPath ...Files.copy(sourcePath, targetPath.resolve(basePath.relativize(sourcePath));

移动文件

移动文件同样简单明了–移动(路径源,路径目标,CopyOption…选项);

可用的StandardCopyOptions枚举是:

  1. StandardCopyOption.REPLACE_EXISTING
  2. StandardCopyOption.ATOMIC_MOVE

如果使用StandardCopyOption.COPY_ATTRIBUTES调用Files.move,则会引发UnsupportedOperationException。 可以在空目录上调用Files.move,或者如果它不需要移动目录内容,例如重新命名,则调用将成功,否则将引发IOException(我们将在下一节中介绍如何移动非空目录)。 如果目标文件已经存在,则默认为引发Exception。 如果源是符号链接,则链接本身将被移动,而不是链接的目标。 这是Files.move的示例,再次使用Path.relativize和Path.resolve方法:

Path sourcePath ...Path basePath ...Path targetPath ...Files.move(sourcePath, targetPath.resolve(basePath.relativize(sourcePath));

复制和移动目录

Files.walkFileTree是在Files类中找到的更有趣和有用的方法之一。 walkFileTree方法执行文件树的深度优先遍历。 有两个签名:

  1. walkFileTree(路径开始,设置选项,int maxDepth,FileVisitor访问者)
  2. walkFileTree(路径开始,FileVisitor访问者)

Files.walkFileTree的第二个选项使用EnumSet.noneOf(FileVisitOption.class)和Integer.MAX_VALUE调用第一个选项。 在撰写本文时,只有一个文件访问选项– FOLLOW_LINKS。 FileVisitor是一个接口,其中定义了四个方法:

  1. preVisitDirectory(T dir,BasicFileAttributes attrs)在遍历所有整数之前调用目录。
  2. visitFile(T file,BasicFileAttributes attrs)调用目录中的文件。
  3. postVisitDirectory(T dir,IOException exc)仅在遍历所有文件和子目录之后才调用。
  4. visitFileFailed(T file,IOException exc)调用了无法访问的文件

所有方法都返回四个可能的FileVisitResult枚举之一:

  1. FileVistitResult.CONTINUE
  2. FileVistitResult.SKIP_SIBLINGS(继续而不遍历目录或文件的同级)
  3. FileVistitResult.SKIP_SUBTREE(继续而不遍历目录内容)
  4. FileVistitResult.TERMINATE

为了使生活更轻松,有一个默认的FileVisitor实现,即SimpleFileVisitor(validate参数不为null并返回FileVisitResult.CONTINUE),可以将其子类化,您可以覆盖您需要使用的方法。 让我们看一个用于复制整个目录结构的基本示例。

复制目录树示例

让我们看一下扩展用于复制目录树的SimpleFileVisitor的类(为清晰起见,省略了一些详细信息):

public class CopyDirVisitor extends SimpleFileVisitor<Path> {private Path fromPath;private Path toPath;private StandardCopyOption copyOption = StandardCopyOption.REPLACE_EXISTING;....@Overridepublic FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {Path targetPath = toPath.resolve(fromPath.relativize(dir));if(!Files.exists(targetPath)){Files.createDirectory(targetPath);}return FileVisitResult.CONTINUE;}@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {Files.copy(file, toPath.resolve(fromPath.relativize(file)), copyOption);return FileVisitResult.CONTINUE;}
}

在第9行中,将遍历源文件“ fromPath”中的每个目录,并在目标“ toPath”中创建每个目录。 在这里,我们可以看到Path对象在处理目录和文件方面的强大功能。 随着代码深入目录结构,只需分别在fromPath和toPath对象上调用relativize和resolve即可构造正确的Path对象。 我们根本不需要知道我们在目录树中的位置,因此不需要繁琐的StringBuilder操作即可创建正确的路径。 在第17行,我们看到用于将文件从源目录复制到目标目录的Files.copy方法。 接下来是删除整个目录树的简单示例。

删除目录树示例

在此示例中,SimpleFileVisitor已被子类化,用于删除目录结构:

public class DeleteDirVisitor  extends SimpleFileVisitor<Path> {@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {Files.delete(file);return FileVisitResult.CONTINUE;}@Overridepublic FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {if(exc == null){Files.delete(dir);return FileVisitResult.CONTINUE;}throw exc;}
}

如您所见,删除是一个非常简单的操作。 只需删除找到的每个文件,然后在退出时删除目录即可。

将Files.walkFileTree与Google Guava结合

前两个示例虽然有用,但非常“香草”。 让我们看一下另外两个示例,它们结合了Google Gauva Function和Predicate接口,更具创意。

public class FunctionVisitor extends SimpleFileVisitor<Path> {Function<Path,FileVisitResult> pathFunction;public FunctionVisitor(Function<Path, FileVisitResult> pathFunction) {this.pathFunction = pathFunction;}@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {return pathFunction.apply(file);}
}

在这个非常简单的示例中,我们将SimpleFileVisitor子类化,以将Function对象作为构造函数参数,并且在遍历目录结构时,将该函数应用于每个文件。

public class CopyPredicateVisitor extends SimpleFileVisitor<Path> {private Path fromPath;private Path toPath;private Predicate<Path> copyPredicate;public CopyPredicateVisitor(Path fromPath, Path toPath, Predicate<Path> copyPredicate) {this.fromPath = fromPath;this.toPath = toPath;this.copyPredicate = copyPredicate;}@Overridepublic FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {if (copyPredicate.apply(dir)) {Path targetPath = toPath.resolve(fromPath.relativize(dir));if (!Files.exists(targetPath)) {Files.createDirectory(targetPath);}return FileVisitResult.CONTINUE;}return FileVisitResult.SKIP_SUBTREE;}@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {Files.copy(file, toPath.resolve(fromPath.relativize(file)));return FileVisitResult.CONTINUE;}
}

在此示例中,CopyPredicateVisitor接收一个Predicate对象,并且基于返回的布尔值,不会复制部分目录结构。 我想指出的是,前面两个示例(除了有用性之外)确实可以在本文后面提供的源代码中进行单元测试。

DirUtils

在到目前为止所讨论的所有内容的基础上,我无法抗拒创建实用程序类DirUtils的机会, 该类是使用以下提供以下方法的目录的抽象:

//deletes all files but leaves the directory tree in placeDirUtils.clean(Path sourcePath);//completely removes a directory treeDirUtils.delete(Path sourcePath);//replicates a directory treeDirUtils.copy(Path sourcePath, Path targetPath);//not a true move but performs a copy then a delete of a directory treeDirUtils.move(Path sourcePath, Path targetPath);//apply the function to all files visitedDirUtils.apply(Path sourcePath,Path targetPath, Function function);

虽然我不愿意说它已经可以生产了,但是写起来很有趣。

结论

这就包装了java.nio.file包提供的新的复制和移动功能。 我个人认为它非常有用,并且可以减轻使用Java中文件的痛苦。 有关符号链接,流复制方法,DirectoryStreams等的更多内容,请务必坚持。 谢谢你的时间。 一如既往地欢迎提出意见和建议。

参考: Java 7的新增功能: JCG合作伙伴提供的 文件和目录的复制和移动   比尔·贝杰克(Bill Bejeck)在“ 编码随机思想”博客上。


翻译自: https://www.javacodegeeks.com/2012/02/java-7-copy-and-move-files-and.html

java高效复制文件并移动

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/357564.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MyEclipse+Tomcat+Java+MySQL实现企业员工信息管理系统

导读:随着信息技术的日益发展已深入到社会的各个角落,各个大的企业,都充分意识到传统的手工管理模式已经逐渐不能适应时代的发展,为了更好的发展,纷纷开发适合自己的管理系统。不管大企业。各种员工信息的小企业也是如此,企业的管理层也深深意识到这一点,以前管理大多为…

T4模板之菜菜鸟篇

一、废话 T4(Text Template Transformation Toolkit)是微软官方在VisualStudio 2008中开始使用的代码生成引擎。在 Visual Studio 中&#xff0c;“T4 文本模板”是由一些文本块和控制逻辑组成的混合模板&#xff0c;它可以生成文本文件。 在 Visual C# 或 Visual Basic 中&…

linux动态库ppt,LINUX系统中动态链接库创建与使用补充_区块链白皮书代写|市场计划书项目PPT设计_Tbleg...

区块链白皮书代写大家都知道&#xff0c;在WINDOWS系统中有很多动态链接库(以.DLL为后缀文件&#xff0c;DLL即Dynamic Link Library)。这种动态链接库&#xff0c;和静态函数库不同&#xff0c;它里面函数并不是执行程序本身一部分&#xff0c;而是根据执行程序需要按需装入&a…

MyEclipse+JavaEE+jsp+sqlsever实现产品售后服务系统

导读:我国信息产业、企业售后服务发展迅速,电商的发展超出了所有人都想象,与此同时也带来了诸多的问题。飞速发展的交易额,带来了大量的GDP增长,然而光鲜的背后是每天无数客服手忙脚乱的为顾客服务。由于顾客对自身生活质量要求越来越高,售后管理业必须随着人们生活水平的…

使用Apache Cassandra设置一个SpringData项目

在这篇文章中&#xff0c;我们将使用Gradle和spring boot来创建一个将spring-mvc和Apache Cassandra数据库集成在一起的项目。 首先&#xff0c;我们将从Gradle配置开始 group com.gkatzioura version 1.0-SNAPSHOTapply plugin: java apply plugin: eclipse apply plugin: i…

西南大学0039c语言作业答案,2017年6月西南大学继续教育学院C语言0039大作业答案...

1、假定p1和p2是已赋值的字符型指针&#xff0c;则下述有关运算中&#xff0c;非法的是(.*(p1-2p2)getchar( ); )2、循环语句for (x0,y0;(y!123)||(x<4);x)&#xff1b;的循环执行(无限次)3、设有定义"int a5,b,*p&a;"&#xff0c;执行下列语句后,b的值不为5的…

第一周学习进度表

第一周所花时间&#xff08;包括上课&#xff09;上课时间&#xff1a;4小时 周三、周五、周六各3小时阅读<<构建之法>>代码量&#xff08;行&#xff09;45博客量4了解到的知识 在上软件工程这门课使我对编程有了哟个新的认识&#xff0c;就是在编写一个复杂程序时…

前端工程师必须知道的用javaScript刷新当前页面的3种方法

业务场景:APP列表页右上角有一个立即刷新按钮,点击立即刷新需要刷新当前页面。下面简单实现几个DEMO 效果图 目录 方法1:reload() 方法 方法2:replace() 方法

【BZOJ1002】[FJOI2007]轮状病毒 递推+高精度

Description 给定n(N<100)&#xff0c;编程计算有多少个不同的n轮状病毒。 Input 第一行有1个正整数n。 Output 将编程计算出的不同的n轮状病毒数输出 Sample Input 3Sample Output 16HINT Source Solution&#xff1a;推导不会&#xff0c;看不懂&#xff0c;知道了公式f[i…

cla c 语言编译器,第九章 CLA_C2000_C_Compiler.pdf

TI CLA C 编译器概述C2000 Compiler RoadmapCGT v6.2CGT v6.1ProductionCGT v6.0Early AdopterIn DevelopmentCGT v5.2FutureCurrent 11Q4 12Q1 12Q2 12Q3 12Q4 13H1 FutureC2000 CGT v5.2 C2000 CGT v6.1 C2000 CGT v6.2•Assembler support for CLA •CLA C support •Future…

新年将至, 程序员如何以代码送出新春祝福

导读:农历新年将至,祝福的话汇成千言万语都寄托在贺卡之中,也许今年你受到了很多的挫折,又或者是顺顺利利度过了一年。但不管怎么样,不管是哭与笑,人生的年轮都已经转过了一圈。我们唯有继续向前走,不要回头,未来的自己取决于现在的自己。有时候一句不经意的问候,一句…

C语言 删除文件 M,最全的C盘可删除文件清单

一、关闭Win7系统休眠功能“以管理员身份运行&#xff0c;所有程序→附件→命令提示符”&#xff0c;右击选择“以管理员身份运行”&#xff0c;进入命令提示符后&#xff0c;手工输入“powercfg -h off” 关闭Win7系统休眠功能;二、关闭系统保护计算机右键属性--高级管理设置-…

身份证/异地身份证在北京办理的解决办法

今年4月18号身份证就到期啦,赶紧抽个时间去补办一个,这种事情一般只能选在工作日,你工作别人也工作的时间段。这个是初中时期弄得身份证,都10年啦,这次在北京补办一下,老家是安徽的。又逢今年在京过年,我太难了。 需要什么材料? 一般来说需要户口本,居住证,还有快要…

小程序--显示图形效果

//运用for循环嵌套循环知识 class Alhh{ public static void main(String[] args){ for(int i0;i<5;i){//控制行数 for(int j0;j<4-i;j){//用-代替空格 System.out.print("-"); } for(int k0;k<i1;k){//*的个数 System.out.print("* "); } System…

jsf集成spring_JSF 2,PrimeFaces 3,Spring 3和Hibernate 4集成项目

jsf集成spring本文展示了如何集成JSF2&#xff0c;PrimeFaces3&#xff0c;Spring3和Hibernate4技术。 它为Java开发人员提供了一个通用的项目模板。 另外&#xff0c;如果Spring不用于业务和数据访问层&#xff0c;则可以提供JSF – PrimeFaces和Hibernate集成项目。 二手技…

linux rc4,Linux kernel 4.8-rc4发布下载,正式版越来越近

距离第三个候选版发布一周时间&#xff0c;Linus Torvalds于今天宣布了Linux Kernel 4.8-rc4&#xff0c;喜欢尝鲜的用户可以下载体验了。Linus Torvalds在邮件中称&#xff0c;Linux kernel 4.8-rc4是目前为止更新幅度最小的一个RC版本了&#xff0c;这也意味着随着正式版距离…

程序员表白,不光需要“技术”,更需要勇气!

回忆起我们的点点滴滴&#xff0c;我们也有美好回忆。程序员应该如何表白呢 &#xff1f;很大一部分是不够自信&#xff0c;怕穷&#xff0c;怕拒绝&#xff0c;其实更多的你可能需要的是一份勇气&#xff0c;爱&#xff0c;要大声说出来&#xff01;恰逢官方正文&#xff0c;在…

休眠:在sqlRestriction上使用联接表别名

如果在复杂查询中使用休眠模式&#xff0c;则需要使用sql。 因此&#xff0c;sqlRestrictions可以解决。 但是&#xff0c;对联接表别名使用sql限制有点棘手。 将有三个表&#xff1a; 公司表。 员工表。 每个员工都属于一家公司&#xff0c;因此我们有多对一的关系。 福…

android 批量查找view,Android Recyclerview实现多选,单选,全选,反选,批量删除的功能

效果图如下:recyclerview 实现多选,单选,全选,反选,批量删除的步骤1.在recyclerview布局中添加上底部的全选和反选按钮,删除按钮,和计算数量等控件2.这里选中的控件没有用checkbox来做,用的是imageview,选中和不选中其实是两张图片3.默认是不显示选中的控件的,点击编辑的时候显…

盘点和程序员相关的那些事,让你不再被割韭菜,薅羊毛!

如今的我们处在一个信息爆炸的时代&#xff0c;光埋头苦恼的闭门造车已经不能满足我们程序员的日常开销啦&#xff0c;因此需要密切关注和自己相关的那些事&#xff01; 目录 1.成功绝非偶然 2.你们公司几号发工资就代表你公司所处的级别 3.各大公司HR对学历的评价&#xff1…