[Java学习日记]高级IO流

目录

一.字节缓冲流

二.字符缓冲流

三.案例:使用字符缓冲流读文件,并排序写出

四.案例:写入文件:运行代码的次数

五.转换流、两种方式指定字符编码读取数据

六.序列化流(输出)反序列化流(输入):属于字节流

七.如何序列化与反序列化多个对象?

八.打印流:只能写,不能读

九.printf中占位符的使用

十.解压

十一.压缩一个文件

十二.压缩文件夹

十三.commons-io工具包

十四.Hutool工具包


一.字节缓冲流

前面的学习是基本流
1.有哪些缓冲流?
带有缓冲区的缓冲流:BufferedInputStream||BufferedOutputStream||BufferedReader||BufferedWriter

2.缓冲流有多少字节的默认缓冲区?
字节缓冲流底层自带8KB的缓冲区:注意,缓冲流是高级流的一种,对基本流做了数据的包装
后面的两个由于在基本流中也有8KB的缓冲区,提高效率不太明显

3。创建缓冲流对象需要传入什么参数?缓冲流相对于基本流有什么特点?
创建对象需要关联基本流,读写数据的依然是基本流,缓冲流的读取效率更高,操作与基本流相似

4.缓冲字节流的传输速度一定比基本字节流的传输速率快吗?
不一定,可以看下面的运行结果:当同为一次性传输8kb的数据的时候,传输速度相近。
如果在底层一次只读取一个字节,有缓冲区的字节流的速度依旧会慢于传递比较大的数组的无缓冲区的字节流的速度

5.在new缓冲字节流时,第二个参数表示什么?
public class Demo291 {
    public static void main(String[] args) throws IOException {
        int i, len;
        long time1, time2;
        byte[] bytes = new byte[8192];
        String src = "C:\\Users\\33428\\Videos\\haniwa\\いつだって戦ってる.mp4";
        String dest = "C:\\Users\\33428\\Desktop\\Haniwa.mp4";


        time1 = System.currentTimeMillis();
        System.out.println("5.设置第二个参数以手动设置缓冲区大小");
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src),8192);
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest));
        System.out.print("一次在底层传输一个字节(有缓冲区):");
        while ((i = bis.read()) != -1) bos.write(i);
        bos.close();
        bis.close();
        time2 = System.currentTimeMillis();
        System.out.println("花费时间"+(time2 - time1)/1000.0+"秒");


        time1 = System.currentTimeMillis();
        bis = new BufferedInputStream(new FileInputStream(src));
        bos = new BufferedOutputStream(new FileOutputStream(dest));
        System.out.print("一次在底层传输8192字节大小数组(有缓冲区):");
        while ((len = bis.read(bytes)) != -1) bos.write(bytes, 0, len);
        bos.close();
        bis.close();
        time2 = System.currentTimeMillis();
        //传递数组总比传递一个字节花费时间少
        System.out.println("花费时间"+(time2 - time1)/1000.0+"秒");


        time1 = System.currentTimeMillis();
        FileInputStream fis = new FileInputStream(src);
        FileOutputStream fos = new FileOutputStream(dest);
        System.out.print("一次在底层传输8192字节大小数组(无缓冲区)");
        while ((len = fis.read(bytes)) != -1) fos.write(bytes,0,len);
        fis.close();
        fos.close();
        time2 = System.currentTimeMillis();
        System.out.println("花费时间"+(time2 - time1)/1000.0+"秒");
    }
}

 

 


 

二.字符缓冲流

1.字符缓冲输入流与缓冲输出流有什么特有方法,这种方法的返回值是什么?
2.使用readline方法时,会读取到换行符号吗?读到空行会返回什么?
3.使用什么方法能够新建一行呢?
public class Demo292 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("JAVA基础\\src\\Day29\\MyText\\b.txt"));
        BufferedWriter bf = new BufferedWriter(new FileWriter("JAVA基础\\src\\Day29\\MyText\\bCopy.txt"));
        System.out.println("1.一次读一行,输出时不同的系统会有不同的换行方式,方法返回字符串");
        String line;
        System.out.println("2.换行符不会读取到,读到空行的时候返回的是空字符串");
        System.out.println("3.使用newline方法能够新建一行");
        while ((line=br.readLine())!=null){
            System.out.println(line+line.length());
            bf.write(line);
            if (line.length() != 0) bf.newLine();
        }
        bf.close();
        br.close();
    }
}

 

  


 

三.案例:使用字符缓冲流读文件,并排序写出

public class Demo293 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("JAVA基础\\src\\Day29\\MyText\\csb.txt"));
        ArrayList<String> arrayList = new ArrayList<>();
        String line;
        while ((line=br.readLine())!=null)arrayList.add(line);
        br.close();

        //这个comparingInt方法里面返回Comparator实现类,在这个方法中只要把对象转换成Integer类型即可
        arrayList.sort(Comparator.comparingInt(o -> Integer.parseInt(o.split("\\.")[0])));

        BufferedWriter bw = new BufferedWriter(new FileWriter("JAVA基础\\src\\Day29\\MyText\\csbSort.txt"));
        for (String s : arrayList) {
            bw.write(s);
            bw.newLine();
        }
        bw.close();
    }
}

 


 

四.案例:写入文件:运行代码的次数

1.在创建字符输出流的时候需要注意的事情?
会更新文件里面的数据
2.快速把基本数据类型变成字符串的方法?
数据+""
public class Demo294 {
    public static void main(String[] args) throws IOException {
        File file = new File("JAVA基础\\src\\Day29\\MyText\\myini.txt");
        if (!file.exists())file.createNewFile();
        BufferedReader br = new BufferedReader(new FileReader(file));

        String line = br.readLine();
        BufferedWriter bw = new BufferedWriter(new FileWriter(file));

        if (line==null||line.length()==0){
            bw.write("1");
            System.out.println("欢迎使用本软件,第1次使用免费");
        }else {
            int i = (Integer.parseInt(line)+1);
            if (i>3){
                System.out.println("本软件只能免费使用三次,欢迎您注册会员之后使用");
            }else {
                bw.write(i+"");
                System.out.println("欢迎使用本软件,第"+i+"次使用免费");
            }
        }
        bw.close();
        br.close();
    }
}

 


 

五.转换流、两种方式指定字符编码读取数据

转换流是属于字符流,这个名字中,字符流字节流都占
是字符流与字节流之间的桥梁,字节流+转换流->字符流
1.创建转换流需要用到的参数是?
字节流
2.转换流属于字符流还是字节流?
字符流
3.转换流有哪些?
InputStreamReader与OutputStreamWriter
4.使用字节流创建转换流,再使用转换流创建字符缓冲流,需要close的流是哪一个呢?
最后创建的字符缓冲流

案例:两种方式指定字符编码读取数据
5.如何使用转换流指定读写字符?
6.如何使用字符流指定读写字符?
7.如何转换字符编码呢?
8.如何使用字节流读取一行数据呢?
public class Demo295 {

    public static void main(String[] args) throws IOException {
        int i;
        String src ="JAVA基础\\src\\Day29\\MyText\\GBK.txt" ;
        String dest = "JAVA基础\\src\\Day29\\MyText\\GBKCopy.txt";

        System.out.println("1.创建对象时指定字符编码,第二个参数使用字符串指定字符编码");
        InputStreamReader isr = new InputStreamReader(new FileInputStream(src),"GBK");
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(dest), "GBK");
        while ((i=isr.read())!=-1) osw.write(i);
        osw.close();
        isr.close();

        System.out.println("2.JDK11之后可以使用FileReader,FileWriter指定字符编码,使用Charset的静态方法获取charset对象");
        FileReader fr = new FileReader(src, Charset.forName("GBK"));
        FileWriter fw = new FileWriter(dest, Charset.forName("GBK"));
        while ((i=fr.read())!=-1){
            fw.write(i);
        }
        fw.close();
        fr.close();

        System.out.println("3.案例:读GBK写UTF-8,在创建读写对象的时候指定即可");
        fr = new FileReader(src, Charset.forName("GBK"));
        fw = new FileWriter(dest);
        while ((i=fr.read())!=-1)fw.write(i);
        fw.close();
        fr.close();

        System.out.println("4.使用字节输入流读取一整行数据,字节流-转换流-缓冲字符流");
        FileInputStream fis = new FileInputStream("JAVA基础\\src\\Day29\\MyText\\b.txt");
        isr = new InputStreamReader(fis);
        BufferedReader br = new BufferedReader(isr);
        System.out.println(br.readLine());
        br.close();
    }
}

 

 


 

六.序列化流(输出)反序列化流(输入):属于字节流

可以把Java中的对象写到本地文件中,看不懂改不了

1.需要序列化的对象有什么要求?
序列化对象需要让javabean类实现serializable接口,标记型接口,之前还有一个Cloneable

2.对于实现serializable接口的实现类,如果没有指定其序列号其序列版本号是不变的吗?序列化和反序列化需要版本号相同吗?
Java会根据类里面的所有内容去生成一个序列号,如果修改的类的代码,版本号会变化,序列化和反序列化的版本号需要保持一致

3.序列化版本号如何定义?
版本号起名规则:私有long常量,名字必须叫serialVersionUID:可以设置一下IDEA自动提示与生成

4.不想序列化到本地的变量该如何处理?
不想序列化到本地的成员变量使用transient修饰符修饰(瞬态)

5.序列化与反序列化的类名?
ObjectInputStream与ObjectOutputStream

6.如何定义序列化与反序列化流?

7.序列化与反序列化应该使用什么方法?
public class Student implements Serializable{
    //序列版本号
    @Serial
    private static final long serialVersionUID = -6236032588385694199L;
    private String name;
    private int age;
    //不想序列化到本地的使用transient修饰符(瞬态)
    private transient String address;
    public Student() {
    }

    public Student(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}
public class Demo296 {
    static String str = "JAVA基础\\src\\Day29\\MyObject\\a.txt";
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Student stu  = new Student("SunCoya",20,"沅江");
        System.out.println("1.使用字节基本流创建序列化与反序列化对象");
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(str));
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(str));
        System.out.println("1.使用writeObject方法序列化对象,使用readObject方法反序列化对象");
        oos.writeObject(stu);
        stu = (Student) ois.readObject();
        System.out.println(stu);
        oos.close();
        ois.close();
    }
}

 


 

七.如何序列化与反序列化多个对象?

public class Demo297 {
    static String str = "JAVA基础\\src\\Day29\\MyObject\\multiObjects.txt";
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Student s1 = new Student("zhangsan",23,"nanjin");
        Student s2 = new Student("lisi",24,"chongqing");
        Student s3 = new Student("wangwu",25,"wuhan");
        System.out.println("在读对象的时候读完的时候再读会报错,所以只传一个对象进去:ArrayList");
        ArrayList<Student> arrayList = new ArrayList<>();
        Collections.addAll(arrayList,s1,s2,s3);

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(str));
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(str));
        oos.writeObject(arrayList);
        for (Student student : (ArrayList<Student>) ois.readObject())
            System.out.println(student);
        oos.close();
        ois.close();
    }
}

 


 

八.打印流:只能写,不能读

1.打印流分为哪两种?用什么类名表示?
分为字节打印流和字符打印流:PrintStream与PrintWriter

2.打印流的特有方法?

3.如何创建打印字节流与打印字符流?

4.平常使用的输出语句,out是一个什么样的变量?默认指向哪里?
public class Demo298 {
    public static void main(String[] args) throws IOException {
        String str = "JAVA基础\\src\\Day29\\MyText\\printStreamAndWriter.txt";
        PrintStream ps = new PrintStream(str);
        ps = new PrintStream(new FileOutputStream(str));
        ps = new PrintStream(new BufferedOutputStream(new FileOutputStream(str)),true,"GBK");
        ps.println("1.打印流的特有方法有:printf,println,print方法");
        ps.println("2.字节打印流在底层通过字节流创建,有多种创建方式(传递字符串或io字节流对象)");
        ps.println("传递参数能够使其自动刷新和指定字符串的输出编码");
        ps.close();


        PrintWriter pw = new PrintWriter(new FileWriter(str, Charset.forName("GBK"),true),true);
        pw.println("字符打印流与字节打印流类似,需要传递字符流,能够指定自动刷新");
        pw.println("3.System中的out变量是一个PrintString静态变量,在虚拟机启动时由虚拟机创建,默认指向控制台");
        pw.close();
    }
}

 


 

九.printf中占位符的使用

public class Demo299 {
    public static void main(String[] args) throws FileNotFoundException {
        String str = "JAVA基础\\src\\Day29\\MyText\\printStream.txt";
        PrintStream ps = new PrintStream(str);
        //% n表示换行
        ps.printf("8>3的结果是:%b %n", 8 > 3);
        ps.printf("100的16进制数是:%x %n", 100);
        ps.printf("100的8进制数是:%o %n", 100);
        ps.printf("计算的结果转16进制:%a %n", 50 * 0.85);
        ps.printf("计算的结果转科学计数法表示:%e %n", 50 * 0.85);
        ps.printf("带有百分号的符号表示法,以百分之85为例:%d%% %n", 85);
        ps.println("---------------------");

        ps.printf("数字前面带有0的表示方式:%03d %n", 7);
        ps.printf("数字前面带有0的表示方式:%04d %n", 7);
        ps.printf("数字前面带有空格的表示方式:% 8d %n", 7);
        ps.printf("整数分组的效果是:%,d %n", 9989997);
        ps.println("---------------------");

        //最终结果是10位,小数点后面是5位,不够在前面补空格,补满10位
        //如果实际数字小数点后面过长,但是只规定两位,会四舍五入
        //如果整数部分过长,超出规定的总长度,会以实际为准
        ps.printf("一本书的价格是:%2.5f元%n", 49.8);
        ps.printf("%(f%n", -76.04);

        //%f,默认小数点后面7位,
        //<,表示采取跟前面一样的内容
        ps.printf("%f和%3.2f %n", 86.04, 1.789651);
        ps.printf("%f和%<3.2f %n", 86.04, 1.789651);
        ps.println("---------------------");

        Date date = new Date();
        // %t 表示时间,但是不能单独出现,要指定时间的格式
        // %tc 周二 12月 06 22:08:40 CST 2022
        // %tD 斜线隔开
        // %tF 冒号隔开(12小时制)
        // %tr 冒号隔开(24小时制)
        // %tT 冒号隔开(24小时制,带时分秒)
        ps.printf("全部日期和时间信息:%tc %n", date);
        ps.printf("月/日/年格式:%tD %n", date);
        ps.printf("年-月-日格式:%tF %n", date);
        ps.printf("HH:MM:SS PM格式(12时制):%tr %n", date);
        ps.printf("HH:MM格式(24时制):%tR %n", date);
        ps.printf("HH:MM:SS格式(24时制):%tT %n", date);

        ps.printf("星期的简称:%ta %n", date);
        ps.printf("星期的全称:%tA %n", date);
        ps.printf("英文月份简称:%tb %n", date);
        ps.printf("英文月份全称:%tB %n", date);
        ps.printf("年的前两位数字(不足两位前面补0):%tC %n", date);
        ps.printf("年的后两位数字(不足两位前面补0):%ty %n", date);
        ps.printf("一年中的第几天:%tj %n", date);
        ps.printf("两位数字的月份(不足两位前面补0):%tm %n", date);
        ps.printf("两位数字的日(不足两位前面补0):%td %n", date);
        ps.printf("月份的日(前面不补0):%te  %n", date);

        ps.printf("两位数字24时制的小时(不足2位前面补0):%tH %n", date);
        ps.printf("两位数字12时制的小时(不足2位前面补0):%tI %n", date);
        ps.printf("两位数字24时制的小时(前面不补0):%tk %n", date);
        ps.printf("两位数字12时制的小时(前面不补0):%tl %n", date);
        ps.printf("两位数字的分钟(不足2位前面补0):%tM %n", date);
        ps.printf("两位数字的秒(不足2位前面补0):%tS %n", date);
        ps.printf("三位数字的毫秒(不足3位前面补0):%tL %n", date);
        ps.printf("九位数字的毫秒数(不足9位前面补0):%tN %n", date);
        ps.printf("小写字母的上午或下午标记(英):%tp %n", date);
        ps.printf("小写字母的上午或下午标记(中):%tp %n", date);
        ps.printf("相对于GMT的偏移量:%tz %n", date);
        ps.printf("时区缩写字符串:%tZ%n", date);
        ps.printf("1970-1-1 00:00:00 到现在所经过的秒数:%ts %n", date);
        ps.printf("1970-1-1 00:00:00 到现在所经过的毫秒数:%tQ %n", date);

        ps.close();
    }
}
8>3的结果是:true 
100的16进制数是:64 
100的8进制数是:144 
计算的结果转16进制:0x1.54p5 
计算的结果转科学计数法表示:4.250000e+01 
带有百分号的符号表示法,以百分之85为例:85% 
---------------------
数字前面带有0的表示方式:007 
数字前面带有0的表示方式:0007 
数字前面带有空格的表示方式:       7 
整数分组的效果是:9,989,997 
---------------------
一本书的价格是:49.80000元
(76.040000)
86.040000和1.79 
86.040000和86.04 
---------------------
全部日期和时间信息:周四 11月 23 10:34:42 CST 2023 
月/日/年格式:11/23/23 
年-月-日格式:2023-11-23 
HH:MM:SS PM格式(12时制):10:34:42 上午 
HH:MM格式(24时制):10:34 
HH:MM:SS格式(24时制):10:34:42 
星期的简称:周四 
星期的全称:星期四 
英文月份简称:11月 
英文月份全称:十一月 
年的前两位数字(不足两位前面补0):20 
年的后两位数字(不足两位前面补0):23 
一年中的第几天:327 
两位数字的月份(不足两位前面补0):11 
两位数字的日(不足两位前面补0):23 
月份的日(前面不补0):23  
两位数字24时制的小时(不足2位前面补0):10 
两位数字12时制的小时(不足2位前面补0):10 
两位数字24时制的小时(前面不补0):10 
两位数字12时制的小时(前面不补0):10 
两位数字的分钟(不足2位前面补0):34 
两位数字的秒(不足2位前面补0):42 
三位数字的毫秒(不足3位前面补0):537 
九位数字的毫秒数(不足9位前面补0):537000000 
小写字母的上午或下午标记(英):上午 
小写字母的上午或下午标记(中):上午 
相对于GMT的偏移量:+0800 
时区缩写字符串:CST
1970-1-1 00:00:00 到现在所经过的秒数:1700706882 
1970-1-1 00:00:00 到现在所经过的毫秒数:1700706882537 


 

十.解压

1.解压缩流与压缩流属于什么流?
解压缩流读与压缩流写属于字节流

2.压缩流中每一个文件在Java中是什么对象?
压缩包里面的每一个文件在Java中都是ZipEntry对象

3.解压缩流与压缩流的类名?
ZipInputStream与ZipOutputStream

解压就是把每一个ZipEntry按照层级结构拷贝到另一个文件当中
1.在windows系统中如何创建解压缩流?需要注意什么?
2.如何获取解压缩流中的每一个文件?
3.使用什么方法判断zipEntry是文件还是文件夹?
4.ZipEntry的toString方法与getName方法返回值是怎么样的?
5.写入文件的时候如何使用zipInputStream,读取的是什么?
6. 当压缩包中的一个文件解压完毕,应该做什么?
public class Demo2910 {
    public static void main(String[] args) throws IOException {
        File src = new File("D:\\Java基础\\day35-基础加强(反射,动态代理).zip");
        File dest = new File("D:\\实验文件夹\\day35-基础加强");

        System.out.println("1.创建解压缩流:用来读取压缩包的数据,依然需使用基本的字节流,需要根据系统指定编码规则");
        ZipInputStream zis = new ZipInputStream(new FileInputStream(src), Charset.forName("GBK"));

        System.out.println("2.使用ZipEntry来获取解压缩流的文件,获取不到则返回为空。");
        ZipEntry zipEntry;
        System.out.println("3.使用isDirectory方法判断ZipEntry是文件还是文件夹");
        System.out.println("4.ZipEntry中toString方法与getName方法返回值一致");
        System.out.println("5.使用zipInputStream中的read方法读取数据,读取的是当前zipEntry中的内容");
        System.out.println("6.压缩一个文件后记得把当前的zipEntry关闭掉,使用解压缩流中的closeZipEntry方法");
        while ((zipEntry=zis.getNextEntry())!=null){
            System.out.println(zipEntry);
            //创建文件夹,这里使用getName与toString都一样
            if(zipEntry.isDirectory())
                new File(dest,zipEntry.getName()).mkdirs();
            else {
                //创建文件:需要读取文件夹,存放到文件中
                File file = new File(dest,zipEntry.getName());
                FileOutputStream fos = new FileOutputStream(file);
                int len;
                byte[] bytes = new byte[1024];
                //这里的读取是在当前entry下
                while ((len=zis.read(bytes))!=-1)fos.write(bytes,0,len);
                fos.close();
                //压缩包中的一个文件处理完毕
                zis.closeEntry();
            }
        }
        zis.close();
    }
}

 


 

十一.压缩一个文件

压缩:把每一个文件或者文件夹看成ZipEntry对象放到压缩包中
1.如何创建压缩流?
2.如何创建ZipEntry对象?传入的参数可以是多级目录吗?
3.写入压缩文件前需要做什么?
4.zos与zis输出与写入的文件由什么决定?
public class Demo2911 {
    public static void main(String[] args) throws IOException {
        File src = new File("D:\\Java基础\\Java基础-资料\\阿里巴巴Java开发手册终极版v1.3.0.pdf");
        File dest = new File("D:\\实验文件夹\\阿里巴巴开发手册.zip");
        System.out.println("1.创建压缩流去关联压缩包,也要记得指定编码");
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(dest), Charset.forName("GBK"));

        System.out.println("2.创建zipEntry对象:表示每一个文件或者文件夹,里面可以传入多级目录");
        ZipEntry zipEntry = new ZipEntry("阿里巴巴Java开发手册终极版v1.3.0.pdf");

        System.out.println("3.写入压缩文件前需要把zipEntry对象放到压缩包当中");
        zos.putNextEntry(zipEntry);

        System.out.println("4.zos写的是最近put的entry,上面的zis读的是最近打开的entry");
        FileInputStream fis = new FileInputStream(src);
        int len;
        byte[] bytes = new byte[1024];
        while ((len = fis.read(bytes))!=-1)zos.write(bytes,0,len);
        fis.close();
        zos.closeEntry();
        zos.close();
    }
}

 


 

十二.压缩文件夹

1.在同一个目录下创建压缩文件夹,可以使用什么方法获取当前文件夹的父目录?
2.压缩文件夹所使用到的递归方法需要用到哪几个参数?
public class Demo2912 {
    public static void main(String[] args) throws IOException {
        File src = new File("D:\\实验文件夹\\day35-基础加强");
        System.out.println("1.在同一个目录下创建压缩文件夹,使用getParentPath获取当前文件夹的父目录");
        File dest = new File(src.getParentFile(),src.getName()+".zip");
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(dest), Charset.forName("GBK"));
        System.out.println("2.参数:传入源,使用的zos,父级目录");
        System.out.println("第二个参数是因为在递归中需要在不同的路径下去把文件压缩到同一个压缩文件中");
        System.out.println("第三个参数是因为new ZipEntry的时候,需要传递字符串:但是不能把完整路径传进去,故传递父级目录");
        System.out.println("在这里因为我需要在zip文件夹里面直接放入src的子文件夹,故先遍历子文件夹,就改写了先判断是否为文件夹的写法。");
        toZip(src, zos, "");
        zos.close();
    }


    public static void toZip(File src, ZipOutputStream zos, String fatherName) throws IOException {
        File[] files = src.listFiles();
        for (File file : files) {
            if (file.isDirectory()) {
                //zip中文件的路径
                String str = fatherName + file.getName() + "\\";
                //放入entry即可创建目录
                zos.putNextEntry(new ZipEntry(str));
                toZip(file, zos, str);
            }
            //下次省else语句的时候还是悠着点吧
            else {
                //是文件
                zos.putNextEntry(new ZipEntry(fatherName + file.getName()));
                FileInputStream fis = new FileInputStream(file);
                int len;
                byte[] bytes = new byte[1024];
                while ((len = fis.read(bytes)) != -1) zos.write(bytes, 0, len);
                fis.close();
                zos.closeEntry();
            }
        }
    }
}

 


 

十三.commons-io工具包

Commons里面有许多工具类,这里只讲解io:Apache的IO操作工具包
可以看到jar包有五个,有后缀的是javadoc文档source资源以及test测试jar包
这里只要第一个:commons-io-2.11.0.jar
public class Demo2913 {
    public static void main(String[] args) throws IOException {
        String str = "D:\\IDEACode\\demo1\\JAVA基础\\src\\Day29\\Mycommons-io";
        //快速拷贝文件,拷贝文件夹,拷贝文件夹到指定目录,删除文件夹,清空文件夹
        FileUtils.copyFile(new File(str, "a.txt"), new File(str, "aCopy.txt"));
        FileUtils.copyDirectory(new File(str), new File(str + "2"));
        FileUtils.copyDirectoryToDirectory(new File(str), new File(str+"2"));
        FileUtils.deleteDirectory(new File(str+"2","Mycommons-io"));
        FileUtils.cleanDirectory(new File(str+"2"));
    }
}

 


 

十四.Hutool工具包

帮助文档:https://apidoc.gitee.com/dromara/hutool/
public class Demo2914 {
    public static void main(String[] args) {
        File file = FileUtil.file("D:\\IDEACode\\demo1\\JAVA基础\\src\\Day29\\MyHutool\\a.txt");
        //无需mkdirs再创建文件,全部路径创建
        File touch = FileUtil.touch(file);
        System.out.println(touch);

        //在文件中写入集合(换行)第四个参数确定是否续写,一行数据为集合中的一个元素
        ArrayList<String> arrayList = new ArrayList<>();
        Collections.addAll(arrayList,"aaa","bbb","ccc");
        FileUtil.writeLines(arrayList,touch,"UTF-8",false);
        FileUtil.writeLines(arrayList,touch,"UTF-8",true);

        //读取文件到集合当中:指定编码
        List<String> list = FileUtil.readLines(touch, "UTF-8");
        System.out.println(list);
        list = FileUtil.readUtf8Lines(touch);
        System.out.println(list);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值