流的本质是一组有顺序,有起点有终点的数据的集合,是对数据传输的抽象 。JavaIO流根据数据传输特性将流抽象成为各种类,组成了JAVAIO类框架。

io流分类

根据传输数据的类型分为字节流和字符流,根据流向的不同分为输入流和输出流

以下是JAVAIO流框架:

img

InputStream、OutSteam和 Reader 和Writer是两组抽象接口,分别代表了输入字节流、输出字节流和输入字符流和输出字符流。

字节流和字符流的区别:

  1. **读写单位不同。**字节流读写数据按字节为单位读取,字符流读写数据按字符为单位读取,根据码表映射字符,一次可以多去多个字节。
  2. **读写对象不同。**字节流可以读取任意数据包含视频、图片。字符流只能读取文本数据。
  3. 字节流在读取时本身不会使用缓冲区,但字符流是会用到缓冲区的,通过缓冲区来操作文件。

常见的流的使用

  • FileReader / FileWriter 用于文件的读写
  • BufferedInputstream/BufferedOutputStream BufferedReader/BufferedWriter 内置缓存,可以一次性读取写入多个数据,提高读取写入效率
  • PrintWriter 打印流,用于输出文本信息到控制台或文件
  • 可使用System.setIn () System.setOut() System,setErr()替换系统标准输入输出为其他的流

流的基础类:

  • InputStream
  • OutputStream

InputStream

字节层面的读

  • read()
    • int read() 读完会返回-1
    • read(byte b[])
    • read(byte b[])
  • skip(long n)
  • int available() 流里还有多少字节可以读
  • mark()
  • reset() 和mark一起使用
    public static void main(String[] args) {
        byte[] buffer = new byte[1024];

        try {

            int len = System.in.read(buffer);
            String s = new String(buffer, 0, len);

            System.out.println("读到了" + len + "字节");
            System.out.println(s);
            System.out.println("s的长度是:" + s.length());

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

输入:123汉字abc

读到了13字节

s的长度是:9

汉字是两个字节,一个字符

文件流

  • FileInputStream
  • FileOutPutStream
  • 对文件进行读写操作
  • 实际工程中已经较少使用
    • 更常用的是以在内存数据或通信数据上建立的流,如数据库的二进制数据读写或网络端口通信
    • 具体的文件读写往往有更专业的类,比如配置文件和日志文件
    public static void main(String[] args) {
        byte[] buf = new byte[10];

        for(int i = 0; i < buf.length; i++){

            buf[i] = (byte)i;
        }

        try {
            //在当前目录建立,如果已经存在,会覆盖掉,如果没有,新建一个文件
            FileOutputStream out = new FileOutputStream("a.dat");
            out.write(buf);
            out.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

流过滤器

以上的流都只能处理单个字节,单个字节读,单个字节写

  • 以一个介质流对象为基础层层构建过滤器流,最终形成的流对象能在数据的输入输出过程中,逐层使用过滤器流的方法来读写数据
   public static void main(String[] args) {

        try {
            //输入字节以外的数据,即用二进制写
            DataOutputStream out = new DataOutputStream(
                    new BufferedOutputStream(
                    new FileOutputStream("a.dat")));

            //在当前目录建立,如果已经存在,会覆盖掉,如果没有,新建一个文件
            int i = 123456;

            out.write(i);
            out.close();

            //用二进制读
            DataInputStream in = new DataInputStream(
                    new BufferedInputStream(
                        new FileInputStream("a.dat")));

            int j = in.readInt();
            System.out.println(j);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }



    }

文本输入输出

InputStream和OutPutStream只能处理字节

DataInputStream和DataOutputStrea只能处理基本数据类型

Reader/Writer

  • 二进制数据采用InputStream/OutputStream
  • 文本数据采用Reader/Writer
   public static void main(String[] args) {


        try {
            PrintWriter out = new PrintWriter(
                    new BufferedWriter(//字符缓冲输出流
                            new OutputStreamWriter(//构建Stream与Writer之间的桥梁,即字符流与字节流
                                    new FileOutputStream("abc.txt"))));//字节流

            int i = 123;
            out.println(i);
            out.close();

            BufferedReader in = new BufferedReader(
                    new InputStreamReader(
                            new FileInputStream("src/main.java")));

            String line;
            while((line = in.readLine()) != null){

                System.out.println(line);

            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

Reader

  • 常用的是BufferReader

  • readLine() 读行

LineNumberReader

  • 可以得到行号
  • getLineNumber()

FileReader

  • InputStreamReader类的子类,所有方法都从父类中继承而来

  • FileReader(File file)

    在给定从中读取数据的File的情况下创建一个新的FileReader

  • FileReader(String fileName)

    在给定从中读取文件名的情况下创造一个新的FileReader

  • FileReader不能指定编码转换方式

汉字编码

            BufferedReader in = new BufferedReader(
                    new InputStreamReader(
                            new FileInputStream("src/main.java"),"utf8"));

为inputStreamReader添加编码参数

格式化输入输出

PrintWriter

  • format(“格式”,……)
  • printf(“格式”,……)
  • print(各种基本类型)
  • println(各种基本类型)

Scanner

在InputStream或Reader上建立一个Scanner对象可以从流中的文本中解析出以文本表达的各种基本类型

  • next…()

什么情况下使用

image-20200804172957027

流的应用

    public static void main(String[] args) {
        try {
            Socket socket = new Socket(InetAddress.getByName("localhost"), 12345);
            PrintWriter out = new PrintWriter(
                    new BufferedWriter(
                            new OutputStreamWriter(
                                    //这里的socket主要指建立起来的连接
                                    socket.getOutputStream())));
            out.println("Hello");
            out.close();
            socket.close();

            BufferedReader in = new BufferedReader(
                    new InputStreamReader(
                            socket.getInputStream()));
            String line;
            line = in.readLine();
            System.out.println(line);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

阻塞/非阻塞

  • read()函数是阻塞的,在读到所需的内容之前就会停下来等

  • 使用read()的更“高级”函数,如nextInt(),readLine()都是这样的

  • 所以常用单独的线程来做socket读的等待,或使用nio的channel选择机制

  • 对于socket,可以设置SO时间

    • setSoTimeOut(int timeOut)

对象串行化

用来将对象转换成流再传递数据

  • ObjectInputStream类
    • readObject()
  • ObjectOutputStream类
    • writerObject()
  • Serializable接口
public class PublicClientDemo {

    public static void main(String[] args) {

        try {
            Student s1 = new Student("John",18,5);
            ObjectOutputStream out = new ObjectOutputStream(
                    new FileOutputStream("obj.dat"));
            out.writeObject(s1);
            out.close();

            ObjectInputStream in = new ObjectInputStream(
                    new FileInputStream("obj.dat"));

            Student s2 = (Student) in.readObject();

            System.out.println(s2);

            System.out.println(s1 == s2);// false
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值