IO流复习
.
File类的使用
1. File类的理解
1. File类的一个对象,代表一个文件或一个文件目录(俗称: 文件夹)
2. File类声明在java.io包下
3. File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法,
并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容。就必须使用IO流来完成
4. 后续File类的对象常会作为参数传递到流的构造器中,指明读取或写入的"终点"。
2. File的实例化
常用构造器
File(String filePath)
File(String parentPath,String childPath)
File(File parentPath,String childPath)
路径的分类
相对路径:相较于某个路径下,指明的路径。
绝对路径:包含盘符在内的路径或文件目录的路径
说明:
IDEA中:
如果大家开发使用Junit中的单元测试方法测试,相对路径即为当前Module下。
如果使用main()测试,相对路径即为当前的Project下。
Eclipse中:
不管使用单元测试方法还是使用main()测试,相对路径都是Project下。
路径分隔符
windows: \\
unix、url: /
3. File类的常用方法
/*
-File类的获取功能:
public String getAbsolutePath(): 获取绝对(完整)路径
public String getPath(): 获取路径
public String getName(): 获取名称
public String getParent(): 获取上层文件目录路径。若无,返回null
public long length(): 获取文件长度(即: 字节数)。 不能获取目录的长度。
public long lastModified(): 获取最后一次的修改时间,毫秒值
如下方法适用于文件目录
public String[] list(): 获取指定目录下的所有文件或者文件目录的名称数组
public File[] listFile(): 获取指定目录下的所有文件或者文件目录的File数组
-File类的重命名功能:
public boolean renameTo(File dest): 把文件重命名为指定的文件路径
-File类的判断功能:
public boolean isDirectory(): 判断是否是文件目录
public boolean isFile(): 判断是否是文件
public boolean exists: 判断是否存在
public boolean canRead(): 判断是否可读
public boolean canWrite(): 判断是否可写
public boolean isHidden(): 判断是否隐藏
-File类的创建功能
public boolean createNewFile(): 创建文件。若文件存在,则不创建,返回false
public boolean mkdir(): 创建文件目录。如果此文件目录存在,就不创建了。
如果此文件目录的上级目录不存在,也不创建。
public boolean mkdirs(): 创建文件目录。如果上级文件目录不存在,一并创建
-File类的删除功能
public boolean delete(): 删除文件或者文件夹
*/
@Test
public void test2(){
File file1 = new File("hello.txt");
File file2 = new File("D:\\io\\hi.txt");
System.out.println(file1.getAbsolutePath());
System.out.println(file1.getPath());
System.out.println(file1.getName());
System.out.println(file1.getParent());
System.out.println(file1.length());
System.out.println(new Date(file1.lastModified()));
System.out.println();
System.out.println(file2.getAbsolutePath());
System.out.println(file2.getPath());
System.out.println(file2.getName());
System.out.println(file2.getParent());
System.out.println(file2.length());
System.out.println(file2.lastModified());
}
@Test
public void test3(){
File file = new File("D:\\321");
String[] list = file.list();
for(String s:list){
System.out.println(s);
}
File[] listFiles = file.listFiles();
for (File f : listFiles){
System.out.println(f);
}
}
/*
public boolean renameTo(File dest): 把文件重命名为指定的文件路径
比如: file1.renameTo(file2)为例
要想保证返回为true,需要file1在硬盘中是存在的,且file2不能在硬盘中存在。
*/
@Test
public void test4(){
File file1 = new File("hello.txt");
File file2 = new File("D:\\io\\hi.txt");
boolean renameTo = file1.renameTo(file2);
System.out.println(renameTo);
}
/*
-File类的判断功能:
public boolean isDirectory(): 判断是否是文件目录
public boolean isFile(): 判断是否是文件
public boolean exists: 判断是否存在
public boolean canRead(): 判断是否可读
public boolean canWrite(): 判断是否可写
public boolean isHidden(): 判断是否隐藏
*/
@Test
public void test5(){
File file1 = new File("hello.txt");
System.out.println(file1.isDirectory());
System.out.println(file1.isFile());
System.out.println(file1.exists());
System.out.println(file1.canRead());
System.out.println(file1.canWrite());
System.out.println(file1.isHidden());
System.out.println();
File file2 = new File("D:\\io");
System.out.println(file2.isDirectory());
System.out.println(file2.isFile());
System.out.println(file2.exists());
System.out.println(file2.canRead());
System.out.println(file2.canWrite());
System.out.println(file2.isHidden());
}
/*
-File类的创建功能: 创建硬盘中对应的文件或文件目录
public boolean createNewFile(): 创建文件。若文件存在,则不创建,返回false
public boolean mkdir(): 创建文件目录。如果此文件目录存在,就不创建了。
如果此文件目录的上级目录不存在,也不创建。
public boolean mkdirs(): 创建文件目录。如果上级文件目录不存在,一并创建
-File类的删除功能: 删除硬盘中对应的文件或文件目录
public boolean delete(): 删除文件或者文件夹
注意事项:
Java中的删除不走回收站
*/
@Test
public void test6() throws IOException {
//文件的创建
File file1 = new File("hi.txt");
if (!file1.exists()){
file1.createNewFile();
System.out.println("创建成功");
}else{//文件存在
file1.delete();
System.out.println("删除成功");
}
}
@Test
public void test7() {
//文件目录的创建
File file1 = new File("D:\\io\\io1\\io3");
boolean mkdir1 = file1.mkdir();
if (mkdir1) {
System.out.println("创建成功1");
}else {
System.out.println("创建失败1");
}
File file2 = new File("D:\\io\\io1\\io4");
boolean mkdir2 = file2.mkdirs();
if (mkdir2) {
System.out.println("创建成功2");
}else {
System.out.println("创建失败2");
}
}
.
IO流概述
1. 流的分类
1. 操作数据单位: 字节流、字符流
2. 数据的流向: 输入流、输出流
3. 流的角色: 节点流、处理流
图示:
2. 流的体系结构
说明:
红框对应的是IO流的4个抽象基类。
蓝框的流需要重点关注
3. 重点说明的几个流结构
抽象基类 节点流 (或文件流) 缓冲流 (处理流的一种)
InputStream FileInputStream (read(byte[] buffer)) BufferedInputStream (read(byte[] buffer))
OutputStream FileOutputStream (write(cbuf,0,len)) BufferedOutputStream (write(cbuf,0,len)) / flush()
Reader FileReader(read(char[] cbuf)) BufferedReader (read(char[] cbuf) / readline())
Writer FileWriter(write(cbuf,0,len)) BufferedWriter (write(cbuf,0,len)) / flush()
4. 输入、输出的标准化过程
输入过程
①创建File的对象,指明读取数据的来源。(要求此文件一定要存在)
②创建相应的输入流,将File类的对象作为参数,传入流的构造器中。
③具体的读入过程:
创建相应的byte[] 或 char[]。
④关闭流资源。
说明: 程序中出现的异常需要使用try-catch-finally处理。
输出过程
①创建File的对象,指明写出数据的位置。(不要求此文件一定要存在)
②创建相应的输出流,将File类的对象作为参数,传入流的构造器中。
③具体的写出过程:
write(char[] / byte[] buffer,0,len);
④关闭流资源。
说明: 程序中出现的异常需要使用try-catch-finally处理。
.
节点流(或文件流)
1. FileReader / FileWriter的使用:
FileReader的使用:
将Note下的hello.txt文件内容读入程序中,并输出到控制台
说明:
1. read()的理解: 返回读入的一个字符。如果达到文件末尾,返回 -1。
2. 异常的处理: 为了保证 流 资源一定可以执行关闭操作。需要使用try-catch-finally处理
3. 读入的文件一定要存在,否则就会报FileNotFoundException。
@Test
public void testFileReader1(){
FileReader fr = null;
try {
//1. File类的实例化
File file = new File("hello.txt");
//2. FileReader流的实例化
fr = new FileReader(file);
//3. 读入的操作
//read(char[] cbuf,):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾,返回 -1。
char[] cbuf = new char[5];
int len;
while ((len =fr.read(cbuf)) != -1 ){
//方式一:
//错误写法:
// for (int i = 0; i < cbuf.length; i++) {
// System.out.print(cbuf[i]);
// }
//正确写法:
// for (int i = 0; i < len; i++) {
// System.out.print(cbuf[i]);
// }
//方式二:
//错误写法:
// String s = new String(cbuf);
// System.out.println(s);
//正确写法:
String s =new String(cbuf,0,len);
System.out.print(s);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fr!=null){
//4. 资源关闭
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
FileWriter的使用:
从内存中写出数据到硬盘文件里。
说明:
1. 输出操作,对应的File可以不存在。并不会报异常。
2. File对应硬盘中的文件,如果不存在,在输出的过程中会自动创建此文件。
File对应硬盘中的文件,如果存在:
如果流使用的构造器是:FileWriter(file,false) / FileWriter(file): 对原有文件的覆盖
如果流使用的构造器是:FileWriter(file,true): 不会对原有文件覆盖,而是在原有文件基础上追加内容
@Test
public void testFileWriter() {
FileWriter fw = null;
try {
//1. 提供File类的对象,指明写出到的文件
File file =new File("hello1.txt");
//2. 提供FileWriter的对象,用于数据的写出
fw = new FileWriter(file,false);
//3. 写出的操作
fw.write("i have a dream!\n");
fw.write("you need to have a dream!");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fw != null){
//4. 流资源的关闭
fw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
文本文件的复制:
@Test
public void testFileWriterFileReader() {
FileReader fr = null;
FileWriter fw = null;
try {
//1. 创建File类的对象,指明读入和写入的文件
File srcFile = new File("hello.txt");
File destFile = new File("hello2");
//不能使用字符流来处理图片等字节数据
// File srcFile = new File("灯光.png");
// File destFile = new File("灯光1.png");
//2. 创建输入流和输出流对象
fr = new FileReader(srcFile);
fw = new FileWriter(destFile);
//3. 数据的读入和写出操作
char[] cbuf = new char[5];
int len;//记录每次读入到cbuf数组中的字符个数
while ((len = fr.read(cbuf))!=-1){
fw.write(cbuf,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4. 关闭流资源
//方式一:
// try {
// if (fw !=null){
// fw.close();
// }
// } catch (IOException e) {
// e.printStackTrace();
// }
// finally{
// try {
// if (fr !=null){
// fr.close();
// }
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
//方式二
try {
if (fw !=null){
fw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fr !=null){
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2. FileInputStream / FileOutputStream的使用
1. 对于文本文件(.txt,.java,.c,.cpp),使用字符流来处理
2. 对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,.md,...),使用字节流来处理
//实现对图片的复制操作
@Test
public void testFileInputStreamFileOutputStream(){
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//1. 创建File类对象,指明输出输入的文件
File srcFile = new File("灯光.png");
File goalFile = new File("灯光2.png");
//2. 创建输出和出入流对象
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(goalFile);
//3. 写入输出操作
byte[] cbuf = new byte[5];
int len;
while ((len = fis.read(cbuf))!=-1){
fos.write(cbuf,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4. 流操作的关闭
try {
if (fos!= null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
【注意点】
相对路径在IDEA 和 Eclipse中使用的区别?
IDEA:
如果使用单元测试方法 (@Test) ,相对路径基于当前Module的。
如果使用main()测试,相对路径基于当前Project工程的。
Eclipse:
单元测试方法(@Test) 还是 main() 都是基于当前Project工程的。
.
缓冲流的使用
1. 缓冲流涉及到的类:
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter
2. 作用:
提供流的读取、写入速度
提高读写速度的原因:
内部提供了一个缓冲区
默认情况下是8kb
3.典型代码:
使用BufferedInputStream和BufferedOutputStream:非文本文件
//实现非文本文件的复制
@Test
public void BufferedInputStreamTest(){
FileInputStream fis = null;
FileOutputStream fos = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
//1. File类的文件创建
File srcFile = new File("灯光.png");
File destFile = new File("灯光3.png");
//2. 流文件对象的创建
//2.1 两个节点流(文件流)
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(destFile);
//2.2 两个缓冲流
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
//3. 复制操作: 读取、写入
byte[] buffer = new byte[10];
int len;
while((len = bis.read(buffer))!=-1){
bos.write(buffer,0,len);
// bos.flush();//刷新缓冲区
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4. 流的关闭
//要求4.1: 先关闭外层的流,再关闭内层的流
if (bis!= null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bis!= null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//说明: 关闭外层流的同时,内层流也会自动的关闭。关于内层流的关闭操作,可以省略。
// fis.close();
// fos.close();
}
}
使用BufferedReader和BufferedWriter:
//使用BufferedReader和BufferedWriter实现文本文件的复制
@Test
public void testBufferedReaderBufferedWriter(){
//创建File类文件和对应流文件
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader(new File("消息信息.txt")));
bw = new BufferedWriter(new FileWriter(new File("消息信息1.txt")));
//复制操作
//方式一: 使用char[]
// char[] buffer = new char[10];
// int len;
// while ((len = br.read(buffer))!=-1){
// bw.write(buffer,0,len);
// }
//方式二: 使用String
String date;
while ((date = br.readLine()) != null){
//方法一:
// bw.write(date+"\n");//date中不包含换行符
//方法二:
bw.write(date);//date中不包含换行符
bw.newLine();//提供换行操作
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭流资源
try {
if (bw != null){
bw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (br != null){
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
.
转换流的使用
1. 转换流涉及到的类: 属于字符流
InputStreamReader: 将一个字节的输入流转换为字符的输入流
解码: 字节、字节数组 --->字符数组、字符串
OutputStreamWriter: 将一个字符的输出流转换为字节的输出流
编码: 字符数组、字符串 --->字节、字节数组
说明: 编码 决定 解码 的方式
2. 作用:
提供字节流与字符流之间的转换
3. 图示:
4. 典型实现:
//InputStreamReader的使用,实现将字节输入流转字符输入流转换
@Test
public void test1(){
java.io.InputStreamReader isr = null;//指明具体使用哪个字符集,其取决于文件消息信息.txt他保存时使用的字符集
try {
FileInputStream fis = new FileInputStream("消息信息.txt");
// java.io.InputStreamReader isr = new java.io.InputStreamReader(fis);//使用系统默认的字符集
isr = new java.io.InputStreamReader(fis,"UTF-8");
char[] cubf = new char[20];
int len;
while ((len = isr.read(cubf)) != -1){
String str = new String(cubf,0,len);
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (isr!=null){
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//将消息信息.txt从字符集UTF-8转换为GBK字符集,使用转换流实现文件的读入和写出转换
@Test
public void test2(){
java.io.InputStreamReader isr = null;
OutputStreamWriter osw = null;
try {
FileInputStream fis = new FileInputStream("消息信息.txt");
FileOutputStream fos = new FileOutputStream("消息信息_gbk.txt");
isr = new java.io.InputStreamReader(fis,"UTF-8");
osw = new OutputStreamWriter(fos,"GBK");
char[] cubf = new char[20];
int len;
while ((len = isr.read(cubf))!= -1){
osw.write(cubf,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (osw != null){
try {
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (isr != null){
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
5. 说明:
文件编码的方式(比如:GBK),决定了解析时使用的(也只能GBK)字符集。
.
编码表(字符集)
1. 常见的编码表
2. 对后面学习的启示
客户端/浏览器端 <—> 后台(java,Go,Python,Node.js,php) <—> 数据库
要求前前后后使用的字符集都要统一: UTF-8
.
其他流的使用
1. 标准的输入输出流:
System.in: 标准的输入流,默认从键盘输入
System.out: 标准的输出流,默认从控制台输出
修改默认的输入和输出行为:
System类的setIn(InputStream is) / setOut(PrintStream ps)方式重新指定输入输出的流。
2. 打印流:
PrintStream 和 PrintWriter
说明:
提供了一系列重载的print() 和 println(),用于多重数据类型的输出
System.out返回的是PrintStream的实例
3. 数据流:
DateInputStream 和 DateOutputStream
作用:
用于读取或写出基本数据类型的变量或字符串
实例代码:
将内存中的字符串、基本数据类型的变量写出到文件中。
*/
//数据写入
@Test
public void test3(){
//1.
DataOutputStream dos = null;
try {
dos = new DataOutputStream(new FileOutputStream("date.txt"));
//2.
dos.writeUTF("阿昌");
dos.flush();//刷新操作,将内存中的数据写入文件
dos.writeInt(21);
dos.flush();
dos.writeBoolean(true);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
//3.
if (dos!= null){
try {
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/*
将文件中存储的基本数据类型和字符串读取到内存中,保存在变量中。
注意点:读取不同类型数据的顺序要按照当初写入的顺序保持一致。
*/
//数据读取
@Test
public void test4(){
DataInputStream dis = null;
try {
//1.
dis = new DataInputStream(new FileInputStream("date.txt"));
//2.
String name = dis.readUTF();
int age = dis.readInt();
boolean isMale = dis.readBoolean();
System.out.println("name="+name);
System.out.println("age="+age);
System.out.println("isMale="+isMale);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (dis != null){
//3.
try {
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
对象流的使用
1. 对象流:
ObjectInputStream 和 ObjectOutputStream
2. 作用:
ObjectOutputStream: 内存中的对象 —>存储中的文件、通过网络传输 :序列化过程
ObjectInputStream : 存储中的文件、通过网络传输 —> 内存中的对象: 反序列化过程
3. 对象的序列化机制
运行把内存中的Java对象转行为二进制流,从而允许把这二进制流持久地保存在磁盘中,
或是通过网络将二进制流传输到另一个网络节点。当其他程序获取到这个二进制流,
就可以将它恢复成原来的Java对象。
4. 序列化代码实现
序列号过程
/*
序列号过程: 将内存中的Java对象保存在磁盘中或通过网络传输出去
使用ObjectOutputStream实现
*/
@Test
public void testObjectOutputStream(){
ObjectOutputStream oos = null;
try {
//1.
oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
//2.
oos.writeObject(new String("我爱敲代码"));
oos.flush();//刷新操作
oos.writeObject(new Person("阿昌",21));
oos.flush();//刷新操作
} catch (IOException e) {
e.printStackTrace();
} finally {
if (oos != null){
try {
//3.
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
5.反序列化代码实现
反序列化过程
/*
反序列化过程: 将磁盘文件中的对象还原为内存中的Java对象
使用ObjectInputStream实现
*/
@Test
public void testObjectInputStream(){
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("object.dat"));
Object obj = ois.readObject();
String str = (String)obj;
Person p =(Person)ois.readObject() ;
System.out.println(str);
System.out.println(p);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (ois != null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
6.实现序列化的对象所属的类需要满足:
1. 需要实现接口: Serializable
2. 需要当前类提供一个全局常量: serialVersionUID,序列版本号
3. 除了当前Person类需要实现Serializable接口之外,还必须保证其内部的所有属性
也必须是可序列号的。(默认情况下,基本数据类型都可序列化)
补充:ObjectInputStream 和 ObjectOutputStream不能序列化static和transient修饰的成员变量
RandomAccessFile的使用
1. 随机存取文件流:
RandomAccessFile
2. 使用说明:
1. RandomAccessFile直接继承于java.lang.Object类,实现了DateInput和DateOutput接口
2. RandomAccessFile既可以作为一个输入流,又可以作为一个输出流。
3. 如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则在执行时自动创建。
写出到的文件存在,则会对原有文件内容,进行覆盖。(默认情况下,从头覆盖)
4. 可以通过相关的操作实现RandomAccessFile"插入"数据的效果 seek(int pos)
3.代码举例
典型代码1:
复制操作,可充当输入输出流
@Test
public void test1(){
RandomAccessFile raf1 = null;
RandomAccessFile raf2 = null;
try {
//1.
raf1 = new RandomAccessFile(new File("灯光.png"),"r");
raf2 = new RandomAccessFile(new File("灯光6.png"),"rw");
//2.
byte[] buffer = new byte[20];
int len;
while ((len = raf1.read(buffer)) != -1){
raf2.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//3.
if (raf1 != null){
try {
raf1.close();
} catch (IOException e) {
e.printStackTrace();
}
if (raf2 != null){
try {
raf2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
典型代码2:
/*
使用RandomAccessFile实现数据的插入效果
*/
@Test
public void test3() throws IOException {
RandomAccessFile raf1 = new RandomAccessFile(new File("hi.txt"),"rw");
raf1.seek(3);//将指针调到3下标位置
//保存3下标后面所有数据到stringBuffer中
StringBuffer stringBuffer = new StringBuffer((int) new File("hi.txt").length());
byte[] buffer = new byte[5];
int len;
while ((len = raf1.read(buffer)) != -1){
stringBuffer.append(new String(buffer,0,len));
}
raf1.seek(3);//将指针调到要插入3下标的位置,插入"Oni_pepe"
raf1.write("Oni_pepe".getBytes());
//写入保存在StringBuffer内的数据到文件中
raf1.write(stringBuffer.toString().getBytes());
raf1.close();
}
Path、Paths、Files的使用
1. NIO的使用说明:
Java NIO (New IO,Non-Blocking IO)是从Java 1.4版本开始引入的一套新 的IO API,可以替代标准的Java IO API
NIO与原来的IO有同样的作用和目 的,但是使用的方式完全不同,NIO支持面向缓冲区的(IO是面向流的)、基于 通道的IO操作。
NIO将以更加高效的方式进行文件的读写操作。
随着 JDK 7 的发布,Java对NIO进行了极大的扩展,增强了对 文件处理和文件系统特性的支持,以至于我们称他们为 NIO.2
2. Path的使用 —jdk7提供
Path的说明:
Path替换原有的File类。
如何实例化:
常用方法:
3. Files工具类 —jdk7提供
作用:
操作文件或文件目录的工具类