IO流

什么是流?

在Java中所有数据都是使用流读写的。流是一组有顺序的有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备之间的传输称为流,流的本质是传输

IO流的分类类:

  • File :文件操作流

  • 字节流(8位的字节):Stream (处理为字节的数据,write/read操作byte[] ,或一个byte)

  • 字符流(16位的字节):Reader、Writer (处理为字符的数据,一般用在文本操作,操作byte[] 、byte、char[]、char)

  • Input / Reader:输入流 (流的方向:读取 / 写入,输入:将数据从各种输入设备(文件、键盘等)读取到内存)

  • Output / Write:输出流 (输出数据写入到各种输出设备(文件(数据,不是设备)、显示器、磁盘))

  • Buffered:缓冲流(开辟缓冲区)

  • 特殊:字节字符流转换流 InputStreamReader、OutputStreamWriter(要把字节转换为字符流,需要在中间套上字节字符转换流)

  • 其他:
    (1) PrintWriter:打印输出流
    (2)StringWriter:字符串输出流
    (3)带Object:对象流

创建流:

  • 直接创建
    (1)文件 输入/输出 字节流
    (2)文件 输入/输出 字符流

  • 流可以包裹另外的流
    (1) 先创建字节/ 字符流,在外包裹其他流

    • 如:new BufferedRead(new FileReader())

    (2)如果设计字节流转换为字符流,中间要使用字节字符转换流

    • 如:new BufferedReader(new InputStreamReader(new
      FileInputStream()))

流的使用

  • 字节流操作:write() / read() byte[],byte
  • 字符流操作:write() / read() char[],char
    ----------------- 特殊的字符操作流:println()

注:可以不停的读取输入流,一直到读取结束:如果read返回值为int,读取到-1结束,若返回值为String,以null返回结束

代码:

import java.io.*;

public class FileInput {
    public static void main(String[] args) throws IOException {
        File file = new File("C:\\Users\\LENOVO\\Documents\\Tencent Files\\1029170395\\FileRecv\\0320.txt");

//        //1.文件字节输入流
//        FileInputStream fis = new FileInputStream(file);
//        //输入流比较固定的写法:读取到一个字节、字符数组,
//        // 先定义read的返回值变量,再while循环
//        byte[] bytes = new byte[1024];
//        int len = 0;
//        while ((len = fis.read(bytes)) != -1) { //读取到的长度,数组可能杜曼,可能未读满,当次读取内容,一般使用数组[0,len]
//            String str = new String(bytes,0,len); //字节数组转字符串 模拟
//            System.out.println(str);
//        }
//        //使用完一定要关闭,反向关闭(和创建顺序相反)
//        fis.close();

//        //2.文件的字符输入流
//        FileReader fr = new FileReader(file);
//        char[] chars = new char[1024];
//        int len = 0;
//        while ((len = fr.read(chars)) != -1) {
//            String str = new String(chars,0,len);
//            System.out.println(str);
//        }
//        fr.close();

//        //3.缓冲流缓冲字节输入,缓冲字符输入
//        //字符输入流
//        //new BufferedReader(new InputStreamReader(new FileInputStream()))

//        FileInputStream fis = new FileInputStream(file);
//        //字节流转字符流,有一定要经过字节字符流转换操作,转换时可以指定编码
//        //和文件格式编码要一致,否则会是乱码,这里默认UTF-8
//        InputStreamReader isr = new InputStreamReader(fis);
//        BufferedReader br  = new BufferedReader(isr);
//        String str ;
//        while ((str = br.readLine()) != null) {
//            System.out.println(str);
//        }
//        //关闭
//        br.close();
//        isr.close();
//        fis.close();

        //4.缓冲的字节输入流
        FileInputStream fis = new FileInputStream(file);
        BufferedInputStream bis = new BufferedInputStream(fis);
        //和之前的字节输入流操作类似 操作byte[]
        byte[] bytes = new byte[1024];
        int len = 0;
        while ((len = bis.read(bytes)) != -1) {
            String str = new String(bytes,0,len);
            System.out.println(str);
        }
        bis.close();
    }
}

注意:缓冲输出流PrintWriter() 输出完需要使用flush() 刷新缓冲区

  • 练习1:把a-z换行输出到某个文件(需要考虑文件是否存在的问题)
import java.io.*;

public class FileOutput {

    public static void main(String[] args) throws IOException {
        //路径上没有该文件,new File不会报错,但是操作输入输出流会抛FileNotFountException
        File file = new File("E:/tmp/1.txt");
        //把a-z换行输出到某个文件,需要考虑文件是否存在的问题
        if(!file.exists()){ //不存在就创建
            file.createNewFile();
        }
        //类似输入的几种写法都是ok
//        new FileWriter() 不带缓冲的字符输出流
//        new FileOutputStream()  文件字节输出流
//        new BufferedWriter() 带缓冲的字符输出流
//        new PrintWriter()

        //缓冲字符输出流
//        BufferedWriter bw = new BufferedWriter(new FileWriter(file));
//        bw.write("\n");

        //打印输出流
        //1.
//        PrintWriter pw = new PrintWriter(new FileWriter(file));
        //2.
        PrintWriter pw = new PrintWriter(new FileOutputStream(file));
        //快速打印a-z
        for(int i='a'; i<='z'; i++){
            pw.println((char)i);
        }
        pw.flush();
    }
}

结果:
在这里插入图片描述

  • 练习2:文件复制
import java.io.*;

public class FileCopy {

    public static void main(String[] args) throws IOException {
        //文件复制
        File input = new File("E:\\360Downloads\\Software\\VisualStudioCommunity\\ch_zh_language.exe");
        File output = new File("E:/tmp/vs.exe");
        if(!output.exists()){
            output.createNewFile();
        }

        //定义输入输出流
        FileInputStream fis = new FileInputStream(input);
        FileOutputStream fos = new FileOutputStream(output);

        long start = System.currentTimeMillis(); //开始时间

        byte[] bytes = new byte[1024*8];
        int len;
        //每次从输入流读取到byte[]的内容,直接输出到某个文件,就是复制
        while((len = fis.read(bytes)) != -1){
            fos.write(bytes, 0, len); //可能读满,可能未读满
        }

        long end = System.currentTimeMillis(); //结束时间

        System.out.println(end-start);
        fis.close();
        fos.close();

        //可以使用缓冲字节输入流、缓冲字节输出流来复制
//        new BufferedInputStream(new FileInputStream())
//        new BufferedOutputStream(new FileOutputStream())
    }
}

序列化和反序列化

  • 序列化:把Java对象转换为其他数据格式的过程。
  • 反序列化:把其他数据转换为Java对象的过程。
    在这里插入图片描述

序列化的使用:

  • 把内存中的对象状态保存到一个文件中或者数据库的时候
  • 用套接字在网络上传送对象的时候

实现序列化的方式:

  1. Java对象序列化
  2. JSON序列化
  3. XML
  4. Protobuf
  5. Hession(它基于HTTP协议传输,使用Hessian二进制序列化,对于数据包比较大的情况比较 友好。)
  6. Dubbo Serialization(阿里dubbo序列化)
  7. FST(高性能、序列化速度大概是JDK的4-10倍,大小是JDK大小的1/3左右)

深拷贝和浅拷贝

都是拷贝a对象为b对象(对象拷贝

  • Java中的浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝。 要求类对象的类实现Clonable接口,使用clone() 复制 有一个缺陷:复杂属性是以复制引用的方式(简单属性回真实复制)

  • Java中的深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容。
    要求类对象的类实现Serializable接口

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值