Java基础学习(15)

一、IO流进阶

1.1 缓冲流

体系图:
在这里插入图片描述
原理:底层自带了长度为8192的缓冲区提高性能

1.1.1字节缓冲流

方法名称说明
public BufferedInputStream(InputStream is)把基本流包装成高级流提高读取数据的性能
public BufferedOutputStream(Outputstream os)把基本流包装成高级流,提高写出数据的性能
import java.io.*;

//通过字节缓冲流来拷贝文件
public class Exercise5 {
    public static void main(String[] args) throws IOException {
        //创建读取的字节缓冲对象
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\Java文件夹\\words\\IOExrecise\\src\\sad\\a.txt"));
        //创建书写的字节缓冲流
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:\\Java文件夹\\words\\IOExrecise\\src\\sad\\b.txt"));

        //循环续写
        int len;
        while ((len = bis.read()) != -1){
            bos.write((char)len);
        }

        //回收资源
        bos.close();
        bis.close();
    }
}

在写的时候要注意:清理资源时,只需要清理字节缓冲流,里面的字节流在源码已经清理

提高效率的原理图:
在这里插入图片描述

主要是节约了读写的时间,在内存当中来回交换数据的时间可以忽略不计

1.1.2 字符缓冲流

方法名称说明
public BufferedReader(Reader r)把基本流变成高级流
public Bufferedwriter(writer r)把基本流变成高级流

字符缓冲流特有方法
在这里插入图片描述

package IO.IO_BufferedStream;

import java.io.*;

public class Dome2 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("src\\IO_Test\\aaaa.txt"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("src\\IO_Test\\aaab.txt"));
        //一次性输入一行
        //String s = br.readLine();
        //System.out.println(s);

        String s ;
        while ((s = br.readLine())!=null){
            //输出的时候需要打印换行
            bw.write(s);
            bw.newLine();
        }
        bw.close();
        br.close();
    }
}

1.2 转换流

是字符流和字节流之间的桥梁
在这里插入图片描述
作用1: 指定字符集读写(淘汰)
作用2:字节流想要使用字符流中的方法
InputStreamReader isr = new InputStreamReader(fis); BufferedReader br = new BufferedReader(isr);

package IO.IO_ConverStream;

import java.io.*;
import java.nio.charset.Charset;

public class Dome1 {
    public static void main(String[] args) throws IOException {
        /*
        JDK11之后就淘汰了
        把GBK编码规则的文件在UTF-8的环境中打印出来
        //"C:\Users\20265\Desktop\ConverDome1.txt"
        InputStreamReader isr =new InputStreamReader(new FileInputStream("C:\\Users\\20265\\Desktop\\ConverDome1.txt"),"GBK");
        //得到里面的数据
        int len;
        while ((len = isr.read())!=-1){
            System.out.print((char) len);
        }
        isr.close();
        */
		//JDK11之后使用的方式
        FileReader fr = new FileReader(new File("C:\\\\Users\\\\20265\\\\Desktop\\\\ConverDome1.txt"), Charset.forName("GBK"));
        //得到里面的数据
        int len;
        while ((len = fr.read())!=-1){
            System.out.print((char) len);
        }
        fr.close();
    }
}

1.3 序列流

可以把java中的对象写到本地文件中

但是我们是看不懂的,但是可以通过反序列流来翻译

在这里插入图片描述

构造方法说明
public ObjectOutputstream(OutputStream out)把基本流包装成高级流
成员方法说明
public final void writeobject(object obi)把对象序列化(写出)到文件中去

序列化流的小细节:

使用对象输出流将对象保存到文件时会出现NotserializableException异常

解决方案: 需要让Javabean类实现Serializable接口

public class Student implements Serializable

package ObjectOutputstreams;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

//初识ObjectOutputstream
public class Dom1 {
    public static void main(String[] args) throws IOException {
        //创建Student对象
        Student stu = new Student("华盛顿", 55);
        //创建序列化流对象
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\Java文件夹\\words\\IOExrecise\\src\\sad\\ab\\e.txt"));
        //写入数据
        oos.writeObject(stu);
        //清理资源
        oos.close();
    }
}

1.4 反序列化流 /对象操作输入流

可以把序列化到本地文件中的对象,读取到程序中来

构造方法说明
public ObjectInputstream(Inputstream out)把基本流变成高级流
成员方法说明
public object readobject()把序列化到本地文件中的对象,读取到程序中来
package ObjectOutputstreams;

import java.io.*;

//初识反序列化流
public class Dom2 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //创建反序列化流对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\Java文件夹\\words\\IOExrecise\\src\\sad\\ab\\e.txt"));

        //读取数据
        Object o = ois.readObject();
        System.out.println(o);
        //清理资源
        ois.close();
    }
}

1.4.1 序列化流/反序列化流的细节汇总

  • 使用序列化流将对象写到文件时,需要让lavabean类实现Serializable接口。否则,会出现NotSerializableException异常
  • 序列化流写到文件中的数据不能修改的,一旦修改就无法再次读回来了
  • 序列化对象后,修改了Javabean类,再次反序列化,会不会有问题?
    会出问题,会抛出InvalidclassException异常
    • 解决方案:给Javabean类添加serialVersionUID (序列号、版本号)
  • 如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
    • 解决方案:给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
package IO.ObjectStream;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Dome1 {
    public static void main(String[] args) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("src\\IO\\ObjectStream\\Dome.txt"));

        oos.writeObject(new Student());

        oos.close();
    }
}
package IO.ObjectStream;

import java.io.Serializable;

public class Student implements Serializable {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    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 toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }
}

1.5 打印流

基本位置展现
在这里插入图片描述
分类:打印流一般是指: PrintStream,PrintWriter两个类

特点

特点1打印流只操作文件目的地,不操作数据源
特点2:特有的写出方法可以实现,数据原样写出
例如:打印:97文件中:97 文件中:true打印: true
特点3:特有的写出方法可以实现自动刷新,自动换行打印一次数据 = 写出 + 行 + 刷新

1.5.1 字节打印流

在这里插入图片描述
在这里插入图片描述

字节流底层没有缓冲区,开不开自动刷新都一样

package MyPrintStream;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.nio.charset.Charset;

//创建
public class Dom1 {
    public static void main(String[] args) throws FileNotFoundException {
        //创建字节打印流
        PrintStream ps = new PrintStream(new FileOutputStream("a.txt"), true, Charset.forName("UTF-8"));

        //利用特殊方法写入数据
        ps.println(97);
        ps.printf("%s嘲笑了%s","张三","李四");
        ps.println();
        ps.print('c');

        //清理资源
        ps.close();
    }
}

1.5.2 字符打印流

字符流底层有缓冲区,想要自动刷新需要开启

在这里插入图片描述
在这里插入图片描述

package MyPrintStream;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;

//创建字符打印流
public class Dom2 {
    public static void main(String[] args) throws IOException {
        //创建字符打印流
        PrintWriter pw = new PrintWriter(new FileWriter("a.txt"), true);

        //添加数据
        pw.println(97);
        pw.printf("%s嘲笑了%s","张三","李四");
        pw.println();
        pw.print('c');

        //清理资源
        pw.close();
    }
}

总结:
1.打印流有几种?各有什么特点?

  • 有字节打印流和字符打印流两种
  • 打印流不操作数据源,只能操作目的地
  • 字节打印流:默认自动刷新,特有的println自动换行
  • 字符打印流:自动刷新需要开启,特有的println自动换行

1.6 解压流、压缩流

结构图:
在这里插入图片描述
解压本质: 把每一个ZipEntry按照层级拷贝到本地另一个文件夹中
解压代码 :

package MyzipStream;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

//解压zip文件
public class MyZipStream {
    public static void main(String[] args) throws IOException {
        //创建一个需要解压的zip文件地址
        File start = new File("E:\\Java文件夹\\words\\IOExrecise\\src\\sad.zip");
        File dest = new File("E:\\");

        //定义一个方法去实现压缩
        Creat(start,dest);
    }

    private static void Creat(File start, File dest) throws IOException {
        //创建zip对象压缩
        ZipInputStream zip = new ZipInputStream(new FileInputStream(start));
        //创建第三方变量来接收获取到的文件(夹)名称
        ZipEntry entrys;
        while ((entrys = zip.getNextEntry()) != null){
            System.out.println(entrys);
            //判断当前是文件还是文件夹
            if (entrys.isDirectory()){
                //是文件夹,就创建一个同名下的文件夹,接收数据
                File file = new File(dest, entrys.toString());
                file.mkdirs();
            }else {
                //是文件,就创建一个同名下的文件,接收数据
                FileOutputStream fos = new FileOutputStream(new File(dest, entrys.toString()));
                int len;
                while ((len = zip.read()) != -1){
                    fos.write(len);
                }
                fos.close();
                //表示当前文件夹已经处理完,开启下一个文件夹
                zip.closeEntry();
            }

        }
        zip.close();
    }
}

压缩文件夹代码:

package MyzipStream;

import java.io.*;
import java.lang.annotation.Target;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


//压缩文件夹
public class MyZipOutStram2 {
    public static void main(String[] args) throws IOException {
        //需要压缩文件的位置
        File start = new File("E:\\Java文件夹\\words\\IOExrecise\\src\\sad");
        //压缩完存放zip的地址
        File destParent = new File("E:\\Java文件夹\\words\\IOExrecise\\src\\");
        File dest = new File(destParent, start.getName()+".zip");
        //创建压缩流
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(dest));
        //获取到上一级名称
        String name = start.getName();
        toZip(start,zos,name);

        zos.close();
    }
    //创建一个方法去压缩文件夹
    private static void toZip(File start, ZipOutputStream zos, String name) throws IOException {
        //遍历源文件
        File[] files = start.listFiles();
        for (File file : files) {
            //进行判断是文件还是文件夹
            if (file.isFile()){
                //是文件,进行下列操作
                //创建ZipEntry对象在里面
                ZipEntry entry = new ZipEntry(name +"\\"+ file.getName());
                //将创建的ZipEntry放入到压缩包当中
                zos.putNextEntry(entry);
               //将数据读取加入到里面
                FileInputStream fis = new FileInputStream(file);
                int len;
                while ((len = fis.read()) != -1){
                    zos.write(len);
                }
                //清理资源
                fis.close();
                zos.closeEntry();

            }else {
                //是文件夹,进行下列操作
                //递归
                toZip(file,zos,name+"\\"+file.getName());
            }
        }
        zos.close();
    }


}

1.7 Commons-io

Commons-io是apache开源基金组织提供的一组有关IO操作的
开源工具包作用:提高IO流的开发效率。

"食用"步骤:

  • 在项目中创建一个文件夹: lib
  • 将jar包复制粘贴到lib文件夹
  • 右键点击jar包,选择Addas Library -> 点击OK
  • 在类中导包使用
FileUtils类(文件/文件夹相关)说明
static void copyFile(File srcFile,File destFile)复制文件
static void copyDirectory(File srcDir,File destDir)static void复制文件夹
copyDirectoryToDirectory(File srcDir,File destDir)复制文件夹
static void cleanDirectory(File directorv)清空文件
static String readFileToString(File file,Charset encoding)夹读取文件中的数据变成成字符串
static void write(File file,CharSequence data,String encoding)写出数据
static void deleteDirectory(File directory)删除文件夹

在这里插入图片描述

package commonsIOs;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;

public class commonsIOsDom1 {
    public static void main(String[] args) throws IOException {
        //源数据地点
        File start = new File("E:\\Java文件夹\\words\\IOExrecise\\src\\sad\\a.txt");
        //拷贝到的地点
        File dest = new File("E:\\Java文件夹\\words\\IOExrecise\\src\\sad\\copy.txt");

        //复制文件
        FileUtils.copyFile(start,dest);

        //复制文件夹(将内容复制)
        File dest1 = new File("E:\\Java文件夹\\words\\IOExrecise\\src\\sad\\copydir");
        File start1 =  new File("E:\\Java文件夹\\words\\IOExrecise\\src\\sad\\ab");
        FileUtils.copyDirectory(start1,dest1);

        //复制文件夹(将文件夹打包全部放到目的文件夹当中)
        FileUtils.copyDirectoryToDirectory(start1,dest1);

        //清空文件夹
        FileUtils.cleanDirectory(dest1);

        //删除文件夹
        FileUtils.deleteDirectory(dest1);
    }
}

1.8 hutool工具包

相关类说明
IoUtil流操作工具类
FileUtil文件读写和操作的工具类
FileTypeUtil文件类型判断工具类
WatchMonitor目录、文件监听
ClassPathResource针对ClassPath中资源的访问封装
FileReader封装文件读取
Filewriter封装文件写入

官网:https://hutool.cn/
API文档:https://apidoc.gitee.com/dromara/hutool/
中文使用文档: https://hutool.cn/docs/#/

相关方法
file: 根据参数创建一个file对象touch: 根据参数创建文件
writeLines: 把集合中的数据写出到文件中,覆盖模式。
appendLines: 把集合中的数据写出到文件中,续写模式。
readLines: 指定字符编码,把文件中的数据,读到集合中。
readutf8Lines: 按照UTF-8的形式,把文件中的数据,读到集合中
copy: 拷贝文件或者文件夹

package Myhutool;

import cn.hutool.core.io.FileUtil;

import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class Dom1 {
    public static void main(String[] args) {

        //添加File对象E:\Java文件夹\words\IOExrecise\a.txt
        File file1 = FileUtil.file("E:\\", "Java文件夹\\words\\", "IOExrecise\\b.txt");
        System.out.println(file1);//E:\Java文件夹\words\IOExrecise\a.txt

        //根据参数来创建文件,文件的若不存在就会自动创建(无父级路径也可以)
        File touch = FileUtil.touch(file1);
        System.out.println(touch);

        //将一个集合导入到文件当中
        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("aaa");
        list.add("aaa");
        FileUtil.writeLines(list,file1,"UTF-8");

        //续写添加集合
        FileUtil.appendLines(list,file1,"UTF-8");

        //读数据,放到一个集合当中存储起来
        List<String> list1 = FileUtil.readLines("E:\\Java文件夹\\words\\IOExrecise\\b.txt", "UTF-8");
        System.out.println(list1);
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值