《JAVA300集》IO流_处理流-day17

目录

节点流和处理流的总述

字节缓冲流

字符缓冲流

转换流

数据流

对象流


节点流和处理流的总述

  • 节点流:可以从或向一个特定的地方(节点)读写数据。如FileReader.
  • 处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。所有处理流的最底层都是节点流一个流对象经过其他流的多次包装,称为流的链接

JAVA常用的节点流:  

  • 文 件     FileInputStream / FileOutputStrean / FileReader / FileWriter 文件进行处理的节点流。
  • 字符串  StringReader / StringWriter 对字符串进行处理的节点流。
  • 数 组     ByteArrayInputStream / ByteArrayOutputStream / CharArrayReader / CharArrayWriter 对数组进行处理的节点流(对应的是内存中的一个数组)。
  • 管 道     PipedInputStream / PipedOutputStream / PipedReader / PipedWriter对管道进行处理的节点流。

常用处理流(关闭处理流使用关闭里面的节点流)

  • 缓冲流:BufferedInputStrean / BufferedOutputStream / BufferedReader / BufferedWriter -Buffered 增加缓冲功能,避免频繁读写硬盘
  • 转换流:InputStreamReader / OutputStreamReader -实现字节流和字符流之间的转换。
  • 数据流:DataInputStream / DataOutputStream -提供将基础数据类型写入到文件/内存数组中,或者读取。保留了数据和数据类型。
  • 对象流:ObjectInputStream / ObjectOutputStream -除了能处理基本数据和字符串外,还包括各种对象,用法类似数据流

流的关闭顺序:

  1. 一般情况下是:先打开的后关闭,后打开的先关闭
  2. 对于有依赖关系的流:如果流a依赖流b,应该先关闭流a,再关闭流b。例如,处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b
  3. 可以只关闭处理流,不用关闭节点流。因为处理流关闭的时候,会调用其处理的节点流的关闭方法。

字节缓冲流

字节缓冲流可以提高读写操作的效率,可以减少硬盘的读写时间,默认的缓冲区大小是8K。

import java.io.*;

// 文件字节输入流,加入缓存流
public class BufferedTest01 {
    public static void main(String[] args) {
        File src = new File("D:/Java/IO/abc.txt");
        BufferedInputStream is = null;
        try{
            is = new BufferedInputStream(new FileInputStream(src)); //把选择的节点流放入处理流
            byte[] flush = new byte[1024]; //缓冲容器,常用1024
            int len = -1;  //接受长度
            while((len=is.read(flush))!=-1){
                // 字节数组—》字符串
                String str = new String(flush,0,len);
                System.out.println(str);
            }
        } catch(IOException e){
            e.printStackTrace();
        } finally {
            try{
                if(null!=is){
                    is.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}

字符缓冲流

import java.io.*;

public class BufferedTest02 {
    public static void main(String[] args) {
        File src = new File("D:/Java/IO/abc.txt");
        BufferedReader reader = null;
        try{
            reader = new BufferedReader(new FileReader(src));
            // 分行读取
            String line = null;
            while((line=reader.readLine())!=null){
                System.out.println(line);
            }
        }catch(IOException e){
            e.printStackTrace();
        }finally{
            try{
                if(null!=reader){
                    reader.close();
                }
            }catch(IOException e){
                e.printStackTrace();
            }
        }
    }
}

转换流

InputStreamReader:从字节流转换为字符流,读取字节,使用指定的charset将其解码为字符。为了效率,通常会包装在BufferedReader里面。

OutputStreamReader:从字符流转换为字节流,为了效率,通常会包装在BufferedWriter里面。

import java.io.*;
/*
* 转换流
* 1. 以字符流的形式操作字节流(纯文本)
* 2,指定字符集
* */
public class ConverTest {
    public static void main(String[] args) {
        // 操作System.in 和 System.out
        BufferedReader reader = null;
        BufferedWriter writer = null;
        try{
            reader = new BufferedReader(new InputStreamReader(System.in,"UTF-8"));
            writer = new BufferedWriter(new OutputStreamWriter(System.out));
            // 循环获取键盘的输入(exit退出),输出此内容
            String msg = "";
            while(!msg.equals("exit")){
                msg = reader.readLine();
                writer.write(msg);
                writer.newLine();
                writer.flush(); //如果不强制刷新,那么只有当缓存满了,才会写出。
            };
        }catch(IOException e){
            e.printStackTrace();
        }finally {
            try{
                if(null!=writer){
                    writer.close();
                }
            }catch(IOException e){
                e.printStackTrace();
            }
            try{
                if(null!=reader){
                    reader.close();
                }
            }catch(IOException e){
                e.printStackTrace();
            }
        }
    }

运行效果:《JAVA300集》IO流_处理流-day17_第1张图片

数据流

数据流提供将基础数据类型写入到文件/内存数组中,或者读取。保留了数据和数据类型

import java.io.*;

/*
* 数据流:
* 1.写出后读取
* 2.读取的顺序与写出保持一致
* DataOutputStream/DataInputStream
* */
public class DataTest {
    public static void main(String[] args) throws IOException {
        // 写出
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos));
        // 操作数据类型+数据
        dos.writeUTF("编码创世界");
        dos.writeBoolean(true);
        dos.writeInt(18);
        dos.flush();
        byte[] datas = baos.toByteArray();
        System.out.println(datas.length);
        //读取
        DataInputStream dis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
        //读取顺序与写出一致,顺序不一致会出现错误
        String msg = dis.readUTF();
        boolean flag = dis.readBoolean();
        int age = dis.readInt();
        System.out.println(flag);
        System.out.println(msg);
    }
}

运行结果:

对象流

对象流除了能处理基本数据和字符串外,还包括各种对象,用法类似数据流,将对象转换成二进制数据流

通过ObjectOutputStream,Object转换为Stream of bytes,称为序列化;反过来的过程,称为反序列化。

注:只有有标识的对象,才可以序列化。

如果序列化的 JDK 版本和反序列化的 JDK 版本不统一,则可能造成异常。因此在序列化操作中引入了一个serialVersionUID 的常量来验证版本的一致性。

import java.io.*;
import java.util.Date;
/*
* 对象流
* 1.写出后读取
* 2.读写顺序一致
* 3.不是所有的对象都可以序列化,对象需要有Serializable接口
* */
public class ObjectTest {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // 写出
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream dos = new ObjectOutputStream(new BufferedOutputStream(baos));
        // 操作数据类型+数据
        dos.writeUTF("编码创世界");
        dos.writeBoolean(true);
        dos.writeInt(18);
        //加入对象
        dos.writeObject("哈哈哈哈哈");
        dos.writeObject(new Date());
        dos.flush();
        byte[] datas = baos.toByteArray();
        //读取
        ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
        //读取顺序与写出一致,顺序不一致会出现错误
        String msg = ois.readUTF();
        boolean flag = ois.readBoolean();
        int age = ois.readInt();
        System.out.println(flag);
        System.out.println(msg);
        System.out.println(age);
        Object str = ois.readObject();
        Object date = ois.readObject();
        //需要手动强制转换类的类型
        if(str instanceof String){  //如果是其实例
            String strObj = (String)str;
            System.out.println(strObj);
        }
        if(date instanceof Date){  //如果是其实例
            Date dateObj = (Date)date;
            System.out.println(dateObj);
        }
    }
}

运行结果:《JAVA300集》IO流_处理流-day17_第2张图片

补充小知识点:

transient表示该数据不需要序列化           

 

你可能感兴趣的:(《JAVA300集》学习,java,对象流,IO流)