1、File
1.1、何为File?
File类的对象代表操作系统的文件(文件、文件夹)
File类提供了诸如:创建文件对象代表文件,获取文件信息(大小、修改时间)、删除文件、创建文件(文件夹)等功能
注:
- File对象可以定位文件和文件夹
 - File封装的对象仅仅是一个路径名,这个路径可以是存在的,也可以是不存在的
 - File类只能对文件本身进行操作,是不能读写文件里面存储的数据
 
1.2、File类常用方法
判断、获取
| 方法名称 | 说明 | 
|---|---|
| public boolean isDirectory() | 判断此路径名表示的File是否为文件夹 | 
| public boolean isFile() | 判断此路径名表示的File是否为文件 | 
| public boolean exists() | 判断此路径名表示的File是否存在 | 
| public long length() | 返回文件的大小(字节数量) | 
| public String getAbsolutePath() | 返回文件的绝对路径 | 
| public String getPath() | 返回定义文件时使用的路径 | 
| public String getName() | 返回文件的名称,带后缀 | 
| public long lastModified() | 返回文件的最后修改时间(时间毫秒值) | 
public static void main(String[] args) {
    File f1 = new File("E:\\test\\poem.txt");
    // f1 是否是目录
    System.out.println(f1.isDirectory());   // false
    // f1 是否是文件
    System.out.println(f1.isFile());    // true
    // f1 是否存在
    System.out.println(f1.exists());        // true
    // 获取 f1 文件名称
    System.out.println(f1.getName());       // poem.txt
    // 获取 f1 的大小 单位:字节
    // 只能获取文件的大小,无法获取文件夹的大小
    // 如果要获取一个文件夹的大小,需要把文件夹里面的所有文件大小进行累加
    long len = f1.length();
    System.out.println(len);        // 12
    // 获取 f1 的文件定义时的路径
    System.out.println(f1.getPath());       // E:\test\poem.txt
    // 获取 f2 的相对路径
    File f2 = new File("index.js");
    System.out.println(f2.getAbsolutePath());       // E:\Code\Java\JavaSE\Review\HighLevel\index.js
    // 获取 f1 文件的最后一次修改时间
    System.out.println(f1.lastModified());      // 61583644800000
}
 
创建、删除
| 方法名称 | 说明 | 
|---|---|
| public boolean createNewFile() | 创建一个新的空的文件 | 
| public boolean mkdir() | 只能创建一级文件夹 | 
| public boolean mkdirs() | 可以创建多级文件夹 | 
| public boolean delete() | 删除指定路径名表示的文件或空文件夹 | 
public static void main(String[] args) throws IOException {
    File file = new File("E:\\one\\two\\three\\index.html");
    // 创建单级目录
    // System.out.println(file.mkdir());
    // 创建多级目录
    // System.out.println(file.mkdirs());
    // 创建一个空的文件
    // 如果存在,则创建失败,反之成功
    // 如果父路径不存在,会报错:IOException
    // 该方法创建的一定是文件,如果没有后缀名,则会创建一个没有后缀的文件
    // System.out.println(file.createNewFile());
    // 删除文件夹/空文件夹
    // 如果删除的是文件,则直接删除且不走回收站
    // 如果删除的是文件夹,则直接删除且不走回收站
    // 如果删除的是带内容的文件夹,则无法进行删除
    System.out.println(file.delete());
}
 
注:delete方法默认只能删除文件和空文件夹,delete方法直接删除不走回收站!
遍历
| 方法名称 | 说明 | 
|---|---|
| public File[] listFiles() | 获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回 | 
public static void main(String[] args) {
    File f1 = new File("E:\\one\\two\\three");
    // 获取 three 文件夹中的所有内容,
    File[] files = f1.listFiles();
    for (File file : files) {
        // file 依次表示 three 文件夹中的每一个文件或者文件夹
        if (file.isFile() && file.getName().endsWith(".html")){
            System.out.println(file);
        }
    }
    File file = new File("D:\\DesktopBackground\\computer");
    // 必须是文件且后缀名为 .png 的文件才会被保存到文件数组中
    File[] files = file.listFiles((File dir, String name) -> {
        // dir:表示当前目录
        // name:表示当前目录下的每个文件
        File f = new File(dir, name);
        return f.isFile() && name.endsWith(".png");
    });
    System.out.println(Arrays.toString(files));
}
 
注:
- 当文件对象表示的路径不存在时,返回null
 - 当文件对象表示的路径是文件时,返回null
 - 当文件对象代表一个空文件夹时,返回一个长度为0的数组
 - 当文件对象是一个有内容的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回
 - 当文件对象是一个有隐藏文件的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件
 - 当没有权限访问该文件夹时,返回null
 
递归删除文件夹
public static void main(String[] args) {
    delDir(new File("E:\\one"));
}
public static void delDir(File src) {
    // 先删除文件夹里面的内容
    File[] files = src.listFiles();
    for (File file : files) {
        // 如果是文件,直接删除
        if (file.isFile()) {
            file.delete();
        } else {
            // 如果是文件夹,递归删除
            delDir(file);
        }
    }
    // 再删除自己
    src.delete();
}
 
2、I/O流
之前编写的程序,是怎么样存储数据的?弊端是什么?
- 在内存中存储的数据是不能长久保存的,在程序结束或者断电的时候数据会丢失!
 
数据希望永久存储,怎么办?
- 使用文件的形式进行存储,文件是存储在计算机硬盘中的,即使断电也不会丢失!
 
2.1、什么是流?
IO流:存储和读取数据的解决方案
流是内存与存储设备之间传输数据的通道

水借助管道传输;数据借助流传输
2.2、流的分类
按流向区分:
- 输入流:I表示intput,把硬盘文件中的数据读入到内存的过程,称之输入,负责读
 - 输出流:O表示output,把内存中的数据写出到硬盘文件的过程,称之输出,负责写
 

按处理数据单元划分:
- 字节流:以字节为单位,可以读写所有数据(图片、视频、音频等)
 - 字符流:以字符为单位,只能读写纯文本数据(txt文件、java文件)
 

2.3、基本(原始)流
字节流
字节输入流
FileInputStream
作用:以内存为基准,把磁盘文件中的数据以字节的形式读取到内存中去
| 构造器 | 说明 | 
|---|---|
| public FileInputStream(File file) | 创建字节输入流管道与源文件对象接通 | 
| public FileInputStream(String pathname) | 创建字节输入流管道与源文件路径接通 | 
| 方法名称 | 说明 | 
|---|---|
| public int read() | 每次读取一个字节返回,如果字节已经没有可读的返回-1 | 
| public int read(byte[] buffer) | 每次读取一个字节数组返回,如果字节已经没有可读的返回-1 | 
public static void main(String[] args) throws Exception {
    // 创建字节输入流对象
    FileInputStream fis = new FileInputStream("E:\\test\\letter.txt");
    // 读取文件:对照的是ASCII码表对应的字符,读取到文件末尾read()方法会返回-1
    // 单个字节读取
    // int r = fis.read();
    // System.out.print((char) r);
    // 循环读取:每次只能读取一个字节
    int len = 0;
    while ((len = fis.read()) != -1) {
        System.out.print((char) len);
    }
    // 释放资源
    fis.close();
}
 
ASCII码对照表
字节输出流
FileOutputStream
作用:以内存为基准,把内存中的数据以字节的形式写出到磁盘文件中去的流
public static void main(String[] args) throws IOException {
    // 创建字节输出流对象
    // 如果文件不存在,会创建一个新的文件,但前提是必须保证父级路径存在!
    // 构造方法参数一:字符串表示的路径,或者是File对象都是可以的
    // 构造方法参数二:为true表示不会清空文件内容,而是在原有基础上追加内容,默认为false,会覆盖文件内容
    FileOutputStream fos = new FileOutputStream("E:\\test\\letter.txt", true);
    // 写出数据
    // 写出的内容,对照的是ASCII码表对应的字符
    // 单个字节写出
    // fos.write(97);
    // 写出字节数组全部数据
    // byte[] bytes = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57};
    // fos.write(bytes);
    // 写出字节数组指定长度
    String str = "hello world";
    byte[] bytes = str.getBytes();
    fos.write(bytes, 6, 5);
    // 释放资源:解除资源占用
    fos.close();
    System.out.println("创建文件成功!");
}
 
使用字节流实现文件的拷贝
public static void main(String[] args) throws IOException {
    long start = System.currentTimeMillis();
    // 创建字节输入流
    FileInputStream fis = new FileInputStream("E:\\baby.mp4");
    // 创建字节输出流
    FileOutputStream fos = new FileOutputStream("E:\\test\\love.mp4");
    // 一边读、一边写
    int len = 0;
    byte[] buffer = new byte[1024];
    // 每次读取多个字节
    while ((len = fis.read(buffer)) != -1) {
        fos.write(buffer, 0, len);
    }
    // 释放资源:先开后关
    fos.close();
    fis.close();
    long end = System.currentTimeMillis();
    System.out.println("拷贝成功!耗时:" + (end - start));
}
 
任何文件的底层都是字节,拷贝是一字不漏的转移字节,只要前后文件格式、编码一致就没有任何问题!
字符集
- GB2312:1980年发布,1981年5月1日实施的简体中文汉字编码国家标准。收录7445个图形字符,其中包括6763个简体汉字
 - BIG5:台湾地区繁体中文标准字符集,共收录13053个中文字,1984年实施
 - GBK:2000年3月17日发布,收录21003个汉字。包含国家标准GB13000-1中的全部中日韩汉字,和BIG5编码中的所有汉字,简体中文版windows系统默认使用GBK
 - Unicode字符集:国际标准字符集(万国码),它将世界各种语言的每个字符定义一个唯一的编码,以满足跨语言、跨平台的文本信息转换
 
汉字存储和展示过程解析

- 计算机中最小存储单元是一个字节
 - ASCII字符集中,一个英文字母占用一个字节,二进制第一位是0
 - GBK中,一个中文汉字占用二个字节,二进制第一位是1
 - UTF-8编码规则中,一个英文字母占用一个字节,一个中文汉字占用三个字节
 
注:
- 读取数据时未读取完整个汉字
 - 字符解码时使用的字符集和编码时使用的字符集必须一致,否则会出现乱码
 - 英文和数字在任何国家的编码中都不会乱码
 
String编码
| 方法名称 | 说明 | 
|---|---|
| byte[] getBytes() | 使用平台的默认字符集将该 String编码为一系列字节,将结果存储到新的字节数组中 | 
| byte[] getBytes(String charsetName) | 使用指定的字符集将该 String编码为一系列字节,将结果存储到新的字节数组中 | 
String解码
| 构造器 | 说明 | 
|---|---|
| String(byte[] bytes) | 通过使用平台的默认字符集解码指定的字节数组来构造新的 String | 
| String(byte[] bytes, String charsetName) | 通过指定的字符集解码指定的字节数组来构造新的 String | 
public static void main(String[] args) throws UnsupportedEncodingException {
    String str = "好好学习 up";
    // 编码
    byte[] bytes = str.getBytes();
    System.out.println(bytes.length);       // 15
    System.out.println(Arrays.toString(bytes));
    byte[] gbks = str.getBytes("GBK");
    System.out.println(gbks.length);        // 11
    System.out.println(Arrays.toString(gbks));
    // 解码
    String str1 = new String(bytes);
    System.out.println(str1);		// 好好学习 up
}
 
字符流
字符输入流
FileReader
作用:以内存为基准,把磁盘文件中的数据以字符的形式读取到内存中去
字符流的底层其实就是字节流
输入流:一次读一个字节,遇到中文时,一次读多个字节
public static void main(String[] args) throws IOException {
    // 创建字符输入流
    FileReader fr = new FileReader("E:\\test\\poem.txt");
    // 读取文件
    // read():默认也是每次读取一个字节,当遇到中文会读取多个,GBK一次读取2个字节,UTF-8一次读取3个字节
    // 读取之后,方法底层还会进行解码并转成十进制
    // int len = 0;
    // while ((len = fr.read()) != -1) {
    // System.out.print((char) len);
    // }
    // 读取文件
    char[] buffer = new char[15];
    int len = 0;
    // read(chars):读取数据、解码、强转合并了,把强转之后的字符放到数组中
    while ((len = fr.read(buffer)) != -1) {
        // 把数组中的数据变成字符串进行打印
        System.out.print(new String(buffer, 0, len));
    }
    // 释放资源
    fr.close();
}
 
字符输出流
FileWriter
作用:以内存为基准,把内存中的数据以字符的形式写出到磁盘文件中去的流
public static void main(String[] args) throws IOException {
    // 创建字符输出流
    FileWriter fw = new FileWriter("E:\\test\\say.txt", true);
    // 写出字符串
    for (int i = 0; i < 10; i++) {
        fw.write("我热爱Java编程语言!!!\n");
    }
    // 写出一个字符数组
    // char[] chars = {'好', '好', '生', '活'};
    // for (int i = 0; i < 6; i++) {
    //     fw.write(chars);
    // }
    // 释放资源
    fw.close();
    System.out.println("写出文件成功!");
}
 
字节流和字符流的使用场景
- 字节流:拷贝任意类型的文件
 - 字符流:读取纯文本文件中的数据。往纯文本文件中写出数据
 
拷贝文件夹中的内容
public static void main(String[] args) throws IOException {
    // 拷贝一个文件夹,考虑子文件夹
    // 创建一个对象表示数据源
    File src = new File("E:\\test");
    // 创建一个对象表示目的地
    File dest = new File("E:\\dest");
    // 调用方法开始拷贝
    copyFile(src, dest);
}
/**
     * 拷贝文件夹
     *
     * @param src  数据源
     * @param dest 目的地
     */
private static void copyFile(File src, File dest) throws IOException {
    dest.mkdirs();
    // 进入到数据源文件夹
    File[] files = src.listFiles();
    // 遍历数组
    for (File file : files) {
        // 判断
        if (file.isFile()) {
            // 是文件,直接拷贝  文件开始 ---> 文件结束
            FileInputStream fis = new FileInputStream(file);
            FileOutputStream fos = new FileOutputStream(new File(dest, file.getName()));
            // 一边读,一边写
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
            // 释放资源
            fos.close();
            fis.close();
        } else {
            // 文件夹,递归拷贝
            copyFile(file, new File(dest, file.getName()));
        }
    }
}
 
2.4、缓冲流
缓冲流也称为高效流、或者高级流。上述的字节流可以称为原始流
- 高效读写
 - 支持输入换行符
 - 可一次写一行,读一行
 
字节缓冲流
作用:字节缓冲流自带长度为8142的缓冲区可以提高原始字节流、字符流读写数据的性能
字节缓冲输入流:BufferedInputStream
字节缓冲输出流:BufferedOutputStream
| 构造器 | 说明 | 
|---|---|
| public BufferedInputStream(InputStream is) | 把基本流包装为高级流,从而提高读取数据的性能 | 
| public BufferedOutputStream(OutputStream os) | 把基本流包装为高级流,从而提高写出数据的性能 | 
使用字节缓冲输入流和字节缓冲输出流拷贝数据
public static void main(String[] args) throws IOException {
    // 创建字节输入流对象
    FileInputStream fis = new FileInputStream("E:\\test\\video\\love.mp4");
    // 创建字节缓冲输入流对象
    BufferedInputStream bis = new BufferedInputStream(fis);
    // 创建字节输出流对象
    FileOutputStream fos = new FileOutputStream("E:\\test\\copy_love.mp4");
    // 创建字节缓冲输出流对象
    BufferedOutputStream bos = new BufferedOutputStream(fos);
    // 循环读取并写入目的地(一次读取多个字节)
    byte[] buffer = new byte[1024];
    int len = 0;
    while ((len = bis.read(buffer)) != -1) {
        bos.write(buffer, 0, len);
    }
    // 释放资源 不需要关闭基本流,底层会自动关闭
    bos.close();
    bis.close();
}
 
字符缓冲流
作用:对于字符流提升不明显,对于字符缓冲流而言关键点是两个特有的方法
字符缓冲输入流:BufferedReader
字符缓冲输出流:BufferedWriter
| 构造器 | 说明 | 
|---|---|
| public BufferedReader(Reader r) | 把基本流变为高级流 | 
| public BufferedWriter(Writer w) | 把基本流变为高级流 | 
字符缓冲流特有方法
| 方法 | 说明 | 
|---|---|
| public String readLine() | 读取一行数据,如果没有数据可读,则返回null | 
| public void newLine() | 跨平台的换行 | 
读取数据
public static void main(String[] args) throws IOException {
    // 创建字符缓冲输入流对象
    BufferedReader br = new BufferedReader(new FileReader("E:\\test\\poem.txt"));
    // 读取数据(可以读取一整行数据,遇到回车换行则结束)
    // String line = br.readLine();
    // System.out.println(line);
    String line = "";
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
    // 释放资源
    br.close();
}
 
写出数据
public static void main(String[] args) throws IOException {
    // 创建字符缓冲输出流对象
    BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\test\\mySong.txt"));
    // 写出数据
    for (int i = 0; i < 10; i++) {
        bw.write((i + 1) + ".我爱他 轰轰烈烈最疯狂");
        // 换行
        bw.newLine();
    }
    // 释放资源
    bw.close();
}
 
2.4、转换流
转换流是字节流和字符串之间的桥梁
字符转换输入流
InputStreamReader:可以把原始的字节流按照指定编码转换成字符输入流
字符转换输出流
OutputStreamWriter:可以把字节输出流按照指定编码转换成字符输出流
应用场景:
-  
指定字符串读写数据(JDK11之后已淘汰)
 -  
字节流需要使用字符流中的方法
 
public static void main(String[] args) throws IOException {
    // 利用转换流按照指定字符编码写出  JDK11已被淘汰
    /* OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\test\\c.txt"), "GBK");
        // 写出数据
        for (int i = 0; i < 6; i++) {
            osw.write("好好生活哦!\n");
        }
        // 释放资源
        osw.close(); */
    // 新的解决方案
    FileWriter fw = new FileWriter("E:\\test\\lan.txt", Charset.forName("GBK"));
    
    // 写出数据
    for (int i = 0; i < 6; i++) {
        fw.write("好好生活哦!\n");
    }
    // 释放资源
    fw.close();
}
 
public static void main(String[] args) throws IOException {
    // 利用字节流读取文件中的数据,每次读取一整行,且不能出现乱码
    // 字节流在读取中文时是会乱码的,字符流可以
    // 字节流没有读取一整行的方法,字符缓冲流可以
    BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("E:\\test\\poem.txt")));
    String line = "";
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
    br.close();
}
 
2.5、序列化流
对象字节输出流
ObjectOutputStream:以内存为基准,把内存中的对象存储到磁盘文件中去,称为对象序列化
| 构造器 | 说明 | 
|---|---|
| public ObjectOutputStream(OutputStream out) | 把低级字节输出流包装成高级的对象字节输出流 | 
| 方法名称 | 说明 | 
|---|---|
| public final void writeObject(Object obj) | 把对象序列化(写出)到本地文件中 | 
public static void main(String[] args) throws IOException {
    // 通过序列化流将对象写到本地文件中
    // 创建学生对象
    Student stu = new Student("小白", 23);
    // 创建序列化流的对象/对象操作输出流
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\test\\obj.txt"));
    // 写出数据
    oos.writeObject(stu);
    // 释放资源
    oos.close();
}
 
对象字节输入流
ObjectInputStream:以内存为基准,把存储到磁盘文件中去的对象数据恢复成内存中的对象,称为对象反序列化
public static void main(String[] args) throws IOException, ClassNotFoundException {
    // 通过反序列化流的对象将序列化的对象文件读取到内存中
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\test\\obj.txt"));
    // 读取并转换
    Student stu = (Student) ois.readObject();
    System.out.println(stu);
    // 释放资源
    ois.close();
}
 
注:
- 需要序列化的对象必须实现Serializable标记接口,否则报错:
NotSerializableException - 如果序列化对象之后,修改了JavaBean,再次序列化会出问题:
InvalidClassException,可以给JavaBean添加serialVersionUID(序列号) - 如果一个对象中的某个成员变量的值不想被序列化,可以给该成员变量添加
transient瞬态关键字。该关键字标记的成员变量不参与序列化过程 - 如果需要序列化多个对象,可以把对象添加到集合中
 
2.6、打印流
作用:打印流可以实现方便、高效的打印数据到文件中去,实现数据原样写出,打印流是没有读取功能的!
应用场景:特殊的打印流,系统中的标准输出流(sout)
| 构造器 | 说明 | 
|---|---|
| public PrintStream(OutputStream/File/String) | 关联字节输出流/文件/文件路径 | 
| public PrintStream(String fileName, Charset charset) | 指定字符编码 | 
| public PrintStream(OutputStream out, boolean autoFlush) | 自动刷新 | 
| public PrintStream(OutputStream out, boolean autoFlush, Charset charset) | 指定字符编码并自动刷新 | 
| 成员方法 | 说明 | 
|---|---|
| public void write(int b) | 常规方法:将指定的字节写出 | 
| public void println(xxx x) | 特有方法:打印任意数据,自动刷新,自动换行 | 
| public void print(xxx x) | 特有方法:打印任意数据,不换行 | 
| public void printf(String format,Object… args) | 特有方法:带有占位符的打印语句,不换行 | 
字节打印流
PrintStream:支持写字节数据出去
public static void main(String[] args) throws IOException {
    // 创建字节打印流对象
    PrintStream ps = new PrintStream(new FileOutputStream("E:\\test\\b.txt"), true, Charset.forName("UTF-8"));
    // 写出数据
    ps.println(100);
    ps.print(true);
    ps.printf("%n%s是我的%s", "你", "眼");
    // 释放资源
    ps.close();
}
 
字节流底层没有缓冲区,开不开刷新都一样
字符打印流
PrintWriter:支持写字符数据出去
public static void main(String[] args) throws IOException {
    // 创建字符打印流的对象
    PrintWriter pw = new PrintWriter(new FileWriter("E:\\test\\c.txt"), true);
    // 写出数据
    pw.println("爱上你是他的错!");
    pw.print("三次握手");
    pw.printf("%n%s是我的%s", "你", "眼");
    // 释放资源
    pw.close();
}
 
字符流底层有缓冲区,想要自动刷新需要开启
2.7、压缩流
压缩流
ZipOutputStream
public static void main(String[] args) throws IOException {
    // 创建File对象表示要压缩的文件
    File src = new File("E:\\test\\2.png");
    // 创建File对象表示压缩包的位置
    File dest = new File("E:\\test");
    toZip(src, dest);
}
private static void toZip(File src, File dest) throws IOException {
    // 创建压缩流关联压缩包
    ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File(dest, "my.zip")));
    // 创建ZipEntry对象,表示压缩包里面的每一个文件和文件夹
    ZipEntry zipEntry = new ZipEntry("2.png");
    // 把创建的ZipEntry对象,放到压缩包中
    zos.putNextEntry(zipEntry);
    FileInputStream fis = new FileInputStream(src);
    int len = 0;
    while ((len = fis.read()) != -1) {
        zos.write(len);
    }
    zos.closeEntry();
    zos.close();
}
 
解压缩流
ZipInputStream
解压本质:把每一个ZipEntry按照层级拷贝到本地另一个文件夹中
public static void main(String[] args) throws IOException {
    // 创建一个 File 表示要解压缩的压缩包
    File src = new File("E:\\test\\video\\movie.zip");
    // 创建一个 File 表示解压的目的地
    File dest = new File("E:\\test");
    unZip(src, dest);
}
public static void unZip(File src, File dest) throws IOException {
    // 解压的本质:就是把压缩包里面的每个文件或文件夹读取处理,按照层级拷贝到目的地中
    // 创建解压缩流读取压缩包中的数据
    ZipInputStream zis = new ZipInputStream(new FileInputStream(src));
    // 获取压缩包里的每一个 ZipEntry 对象
    ZipEntry entry = null;
    while ((entry = zis.getNextEntry()) != null) {
        System.out.println(entry);
        if (entry.isDirectory()) {
            // 文件夹:需要在dest目的地处创建同样的文件夹
            File file = new File(dest, entry.toString());
            file.mkdirs();
        } else {
            // 文件:读取压缩包中的文件,按照层级进行存放
            FileOutputStream fos = new FileOutputStream(new File(dest, entry.toString()));
            int len = 0;
            byte[] buffer = new byte[8192];
            while ((len = zis.read(buffer)) != -1) {
                // 写出目的地
                fos.write(buffer, 0, len);
            }
            fos.close();
            // 压缩包中的一个文件处理完毕
            zis.closeEntry();
        }
    }
    zis.close();
}
 
2.8、Commons-io
commons-io是apache开源基金组织提供的一组有关IO操作的类库,可以提高IO功能开发的效率
commons-io工具包提供了很多有关io操作的类。有两个主要的类FileUtils,IOUtils
public static void main(String[] args) throws IOException {
    // ====== FileUtils ======
    // 复制文件
    // File src = new File("E:\\test\\x\\x.txt");
    // File desc = new File("E:\\test\\x_copy.txt");
    // FileUtils.copyFile(src,desc);
    // 复制文件夹
    // File src = new File("E:\\test\\x");
    // File dest = new File("E:\\test\\x_copy");
    // FileUtils.copyDirectory(src, dest);
    // 清空文件夹
    // FileUtils.cleanDirectory(new File("E:\\test\\x_copy"));
    // 删除文件夹
    // FileUtils.deleteDirectory(new File("E:\\test\\x"));
    // 删除文件
    // FileUtils.delete(new File("E:\\test\\2.png"));
    // 复制文件
    // IOUtils.copy(new FileInputStream("E:\\test\\x_copy.txt"), new FileOutputStream("E:\\test\\x.txt"));
    // ====== IOUtils ======
    // 读取数据
    // List<String> list = IOUtils.readLines(new FileReader("E:\\test\\x.txt"));
    // for (String str : list) {
    //     System.out.println(str);
    // }
    // 写出数据
    // IOUtils.write("期待未来 拥抱变化",new FileOutputStream("E:\\test\\song.txt"));
    // 复制大文件
    IOUtils.copyLarge(new FileInputStream("E:\\test\\movie\\小欢乐.mp4"),new FileOutputStream("E:\\test\\say.mp4"));
}
                













