[NIO.2] 第三十六篇 编写一个文件拷贝应用

本文介绍如何使用Java NIO 2 API实现目录树的完整拷贝,包括递归拷贝文件、目录及其属性。文章详细解释了在拷贝过程中需要注意的关键点,并提供了一个具体的代码示例,展示如何从一个路径复制到另一个路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

拷贝目录树的时候,需要为文件和目录递归调用 Files.copy() 方法。在开始编写代码之前,要注意以下几点:

[list]
[*]在拷贝目录中的文件之前,必须先拷贝目录本身。不管目录中是否有文件,拷贝目录后的结果都将是空目录。这个任务必须在 preVisitDirectory() 中完成。
[*]拷贝文件最好在 visitFile() 方法中进行。
[*]在拷贝文件或目录的过程中,你要考虑是否需要使用 REPLACE_EXISTING 和 COPY_ATTRIBUTES 配置项。
[*]如果你需要保留目录的属性,那么要等到文件拷贝完成后在 postVisitDirectory() 方法中进行操作。
[*]如果你选择了使用目标文件处理软链接(FOLLOW_LINKS),并且在目录树中有循环引用,那么将会触发 visitFileFailed() 方法并抛出 FileSystemLoopException 异常。
[*]如果没有权限访问文件,那么visitFileFailed() 方法需要返回FileVisitResult.CONTINUE 或 TERMINATE,具体返回什么根据你的需求决定。
[*]在拷贝过程中,可以用 FOLLOW_LINKS 选项来用目标文件处理软链接。
[/list]

下面的代码将演示将 C:\rafaelnadal 子目录树拷贝到 C:\rafaelnadal_copy 中:

import java.nio.file.FileSystemLoopException; 
import java.nio.file.attribute.FileTime;
import java.io.IOException;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.EnumSet;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES;

class CopyTree implements FileVisitor {

private final Path copyFrom;
private final Path copyTo;

public CopyTree(Path copyFrom, Path copyTo) {
this.copyFrom = copyFrom;
this.copyTo = copyTo;
}

static void copySubTree(Path copyFrom, Path copyTo) throws IOException {
try {
Files.copy(copyFrom, copyTo, REPLACE_EXISTING, COPY_ATTRIBUTES);
} catch (IOException e) {
System.err.println("Unable to copy " + copyFrom + " [" + e + "]");
}

}

@Override
public FileVisitResult postVisitDirectory(Object dir, IOException exc)
throws IOException {
if (exc == null) {
Path newdir = copyTo.resolve(copyFrom.relativize((Path) dir));
try {
FileTime time = Files.getLastModifiedTime((Path) dir);
Files.setLastModifiedTime(newdir, time);
} catch (IOException e) {
System.err.println("Unable to copy all attributes to: " + newdir+" ["+e+ "]");
}
} else {
throw exc;
}

return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult preVisitDirectory(Object dir, BasicFileAttributes attrs)
System.out.println("Copy directory: " + (Path) dir);
Path newdir = copyTo.resolve(copyFrom.relativize((Path) dir));
try {
Files.copy((Path) dir, newdir, REPLACE_EXISTING, COPY_ATTRIBUTES);
} catch (IOException e) {
System.err.println("Unable to create " + newdir + " [" + e + "]");
return FileVisitResult.SKIP_SUBTREE;
}

return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult visitFile(Object file, BasicFileAttributes attrs)
throws IOException {
System.out.println("Copy file: " + (Path) file);
copySubTree((Path) file, copyTo.resolve(copyFrom.relativize((Path) file)));
return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult visitFileFailed(Object file, IOException exc)
throws IOException {
if (exc instanceof FileSystemLoopException) {
System.err.println("Cycle was detected: " + (Path) file);
} else {
System.err.println("Error occurred, unable to copy:" +(Path) file+" ["+ exc +
"]");
}

return FileVisitResult.CONTINUE;
}
}

class Main {

public static void main(String[] args) throws IOException {

Path copyFrom = Paths.get("C:/rafaelnadal");
Path copyTo = Paths.get("C:/rafaelnadal_copy");

CopyTree walk = new CopyTree(copyFrom, copyTo);
EnumSet opts = EnumSet.of(FileVisitOption.FOLLOW_LINKS);

Files.walkFileTree(copyFrom, opts, Integer.MAX_VALUE, walk);
}
}


运行了上面的代码后,你将发现 C:\rafaelnadal_copy 和 C:\rafaelnadal 将会有完全一样的目录树和属性。

文章来源:[url]http://www.aptusource.org/2014/04/nio-2-writing-a-copy-files-application/[/url]
一、考试基本要求面向对象程序设计考试是为了测试学生是否具备面向对象编程思想和初步应用Java语言编程的能力的考试。考生要求达到以下“知识”和“技能”两方面的目标。 【知识方面】:熟练掌握面向对象程序设计的基本概念,熟练掌握Java语言的编程语法和常用类库的使用。【技能方面】:能正确阅读和理解Java程序,能编写和调试一般功能需求的Java程序。二、考试方式、时间、题型及比例1.考试方式:闭卷笔试2.考试时间:150分钟3.题型比例:总分值为200分,题型为选择20%、简答题20%、程序阅读20%、程序综合设计40%。三、考试内容及考试要求第一章 Java语言概述 [知识要点]: Java语言的产生、应用前景和特点;Java虚拟机及Java运行系统; Java语言和C++语言的相同及不同之处;熟练掌握Java应用程序的编辑、编译和运行过程。 [考试要求]: 1.了解:Java 语言的产生、应用前景和特点; 2.了解:Java虚拟机及Java运行系统; 3.掌握:Java 语言和 C++语言的相同及不同之处; 4.掌握:Java 应用程序编写、编译和运行过程。 第二章 Java 语言基础 [知识要点]:Java 语言的数据类型;变量和常量;正确书写表达式;数组;流程控制。 [考试要求]: 1.了解:数据类型的转换(自动类型转换和强制类型转换);运算符的优先级和结合性; 2.掌握:Java语言各种数据类型; 3.掌握:Java语言算术运算符、关系运算符、逻辑运算符、位运算符和复合赋值运算符的功能及使用; 4.掌握:Java语言变量、常量的使用及其运算操作; 5.掌握:Java语言流程控制语句的功能及使用;6.掌握:Java数组的定义;数组的初始化和数组的应用;二维数组的应用。 第三章 面向对象编程[知识要点]:面向对象的基本概念;面向对象的软件开发过程。 [考试要求]: 1.了解:面向对象的概念;2.掌握:类的创建与使用;3.掌握:方法的定义和使用;4.掌握:对象的基本操作方式;5.掌握:构造方法的定义和使用;6.掌握:this关键字和static关键字的使用;7.理解:成员变量和局部变量的区别。第四章 面向对象的特性 [知识要点]:掌握面向对象的三大特性。 [考试要求]: 1.理解:封装的概念; 2.理解:继承的概念;3.理解:多态的概念;4. 掌握:final关键字的使用5. 掌握:Lambda表示式的使用第五章 抽象类和接口 [知识要点]:抽象类与接口的基本概念以及实际应用。 [考试要求]: 1.掌握:抽象类和接口的使用;2.掌握:Java中的内部类; 2.了解:单例模式; 3.了解:模板设计方法; 第六章 Java异常 [知识要点]:Java异常的基本概念;Java异常处理机制;自定义Java异常类的应用。 [考试要求]: 1.理解:异常的概念; 2.掌握:异常的处理机制;3.掌握:自定义异常的使用第七章 Java常用类[知识要点]:应用Java语言的工具类库。 [考试要求]: 1.掌握:字符串相关类的使用; 2.掌握:System类与Runtime类的使用;3.掌握:Math类与Random类的使用;4.掌握:日期类的使用。第八章 集合框架[知识要点]:应用Java语言的集合框架解决具体问题。 [考试要求]: 1.掌握:List、Map、Set集合的使用; 2.掌握:集合遍历的方法;3.掌握:泛型的使用;4.掌握:集合工具类的使用;5.掌握:Stream API的使用。第九章 Java IO[知识要点]:Java 输入输出与文件处理。 [考试要求]: 1.掌握: File类及其用法; 2.掌握:操作字节流和字符流读写文件;3.了解:其他IO流;4.了解:NIO的概念及其用法;5.了解:常见字符编码。第十章 图形用户界面[知识要点]:Java的Swing组件、容器、布局管理器的概念;图形界面上的事件响应。 [考试要求]: 1.了解: AWT组件和Swing组件的联系和区别; 2.掌握:常用的Swing组件的使用;3.理解:常用的窗体和布局管理器;4.掌握:事件处理机制。第十一章 Java多线程[知识要点]:多线程的基本概念;创建和启动线程;线程的生命周期;多线程同步问题;多线程通信;线程池的概念。 [考试要求]: 1.了解: 进程和线程的区别; 2.掌握:创建线程的方法;3.理解:线程的生命周期及其状态转换;4.掌握:多线程的同步;5.掌握:多线程之间的通信;6.了解:线程池的使用。第十二章 Java网络编程[知识要点]:网络协议;使用Java开发网络程序。 [考试要求]: 1.了解:网络通信协议; 2.了解:UDP通信;3.了解:TCP通信;4.掌握:网络程序的开发。第十三章 JDBC编程[知识要点]:数据库基本概念;JDBC原理;应用JDBC接口操作数据库。 [考试要求]: 1.了解:JDBC原理; 2.掌握:Connection接口、Statement接口、ResultSet接口、PreparedStatement接口的使用;3.掌握:使用JDBC操作数据库。四、其他说明 1.此次考试为笔试考试,不能使用任何的编程机器; 2.所有程序阅读题、编程题或算法设计题均采用程序填空题方式完成。五、参考书目李松阳、马剑威.Java程序设计基础与实战(微课版),人民邮电出版社,2022年8月. ISBN: 9787115591746 根据这个考纲帮我生成三套试卷
最新发布
03-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值