本文内容:

  • 什么是流
  • 字节流
  • 字符流

首发日期:2018-07-24


什么是流

  • 流是个抽象的概念,是对输入输出设备的抽象,输入流可以看作一个输入通道,输出流可以看作一个输出通道。
  • 输入流是相对程序而言的,外部传入数据给程序需要借助输入流。
  • 输出流是相对程序而言的,程序把数据传输到外部需要借助输出流。

什么是字节流?

字节流--传输过程中,传输数据的最基本单位是字节的流。

什么是字符流?

字符流--传输过程中,传输数据的最基本单位是字符的流。

字符编码方式不同,有时候一个字符使用的字节数也不一样,比如ASCLL方式编码的字符,占一个字节;而UTF-8方式编码的字符,一个英文字符需要一个字节,一个中文需要三个字节。

字节数据是二进制形式的,要转成我们能识别的正常字符,需要选择正确的编码方式。我们生活中遇到的乱码问题就是字节数据没有选择正确的编码方式来显示成字符。

从本质上来讲,写数据(即输出)的时候,字节也好,字符也好,本质上都是没有标识符的,需要去指定编码方式。

但读数据的时候,如果我们需要去“看数据”,那么字节流的数据需要指定字符编码方式,这样我们才能看到我们能识别的字符;而字符流,因为已经选择好了字符编码方式,通常不需要再改了(除非定义的字符编码方式与数据原有的编码方式不一致!)

在传输方面上,由于计算机的传输本质都是字节,而一个字符由多个字节组成,转成字节之前先要去查表转成字节,所以传输时有时候会使用缓冲区。


字节流

  • 字节流的类通常以stream结尾

字节输入流:

常用的字节输入流主要有:

  • InputStream
  • FileInputStream
  • BufferedInputStream 【BufferedInputStream不是InputStream的直接实现子类,是FilterInputStream的子类】

    他们的区别与用途:

    • InputStream是字节输入流的抽象基类 ,InputStream作为基类,给它的基类定义了几个通用的函数:

        • read(byte[] b):从流中读取b的长度个字节的数据存储到b中,返回结果是读取的字节个数(当再次读时,如果返回-1说明到了结尾,没有了数据)
        • read(byte[] b, int off, int len):从流中从off的位置开始读取len个字节的数据存储到b中,返回结果是实际读取到的字节个数(当再次读时,如果返回-1说明到了结尾,没有了数据)
        • close():关闭流,释放资源。
    • FileInputStream主要用来操作文件输入流,它除了可以使用基类定义的函数外,它还实现了基类的read()函数(无参的):
        • read():从流中读取1个字节的数据,返回结果是一个int,(如果编码是以一个字节一个字符的,可以尝试转成char,用来查看数据)。
    • BufferedInputStream带有缓冲的意思,普通的读是从硬盘里面读,而带有缓冲区之后,BufferedInputStream已经提前将数据封装到内存中,内存中操作数据要快,所以它的效率要要非缓冲的要高。它除了可以使用基类定义的函数外,它还实现了基类的read()函数(无参的):
        • read():从流中读取1个字节的数据,返回结果是一个int,(如果编码是以一个字节一个字符的,可以尝试转成char,用来查看数据)。

    使用:

    • InputStream是抽象基类,所以它不可以创建对象,但它可以用来“接口化编程”,因为大部分子类的函数基类都有定义,所以利用基类来调用函数。
    • FileInputStream是用来读文件数据的流,所以它需要一个文件对象用来实例化,这个文件可以是一个File对象,也可以是文件名路径字符串.【这里文件不存在会抛错】

    • BufferedInputStream是一种封装别的流以提高效率的流,所以它的初始化需要一个的InputStream流对象。

    字节输出流:

    常用的字节输出流主要有:

    • OutputStream
    • FileOutputStream
    • BufferedOutputStream 【BufferedOutputStream不是OutputStream的直接实现子类,是FilterOutputStream的子类】

    他们的区别与用途:

    • OutputStream是字节输出流的基类, OutputStream作为基类,给它的基类定义了几个通用的函数:

        • write(byte[] b):将b的长度个字节数据写到输出流中。
        • write(byte[] b,int off,int len):从b的off位置开始,获取len个字节数据,写到输出流中。
        • flush():刷新输出流,把数据马上写到输出流中。
        • close():关闭流,释放系统资源。
    • FileOutputStream是用于写文件的输出流,它除了可以使用基类定义的函数外,还实现了OutputStream的抽象函数write(int b):
        • write(int b):将b转成一个字节数据,写到输出流中。
    • BufferedOutputStream像上面那个BufferedInputStream一样,都可以提高效率。它除了可以使用基类定义的函数外,它还实现了OutputStream的抽象函数write(int b):
        • write(int b):将b转成一个字节数据,写到输出流中。

    使用:

    • OutputStream是抽象基类,所以它不能实例化,但它可以用于接口化编程。
    • FileOutputStream是用于写文件的输出流,所以它需要一个文件作为实例化参数,这个文件可以是File对象,也可以是文件路径字符串。【如果文件不存在,那么将自动创建。】【FileOutputStream实例化时可以给第二个参数,第二个参数是是否使用追加写入默认,为true时代表在原有文件内容后面追加写入数据,默认为false】

    • BufferedOutputStream需要一个输出流作为实例化参数。

    补充:

    • 上面的一些函数,考虑到效率问题,上面的子类可能会重写基类的函数,但功能基本是不变的。
    • 更多关于字节流的函数与用法可以参考jdk文档。

    字符流

    • 字符流的类通常以reader和writer结尾

    字符输入流:

    常见的字符输入流有:

    • Reader
    • InputStreamReader
    • FileReader
    • BufferedReader

    他们的区别与用途:

    • Reader是字符输入流的抽象基类 ,它定义了以下几个函数:

        • read() :读取单个字符,返回结果是一个int,需要转成char;到达流的末尾时,返回-1
        • read(char[] cbuf):读取cbuf的长度个字符到cbuf这种,返回结果是读取的字符数,到达流的末尾时,返回-1
        • close()  :关闭流,释放占用的系统资源。
    • InputStreamReader 可以把InputStream中的字节数据流根据字符编码方式转成字符数据流。它除了可以使用基类定义的函数,它自己还实现了以下函数:
      • read(char[] cbuf, int offset, int length) :从offset位置开始,读取length个字符到cbuf中,返回结果是实际读取的字符数,到达流的末尾时,返回-1
    • FileReader 可以把FileInputStream中的字节数据转成根据字符编码方式转成字符数据流。
    • BufferedReader可以把字符输入流进行封装,将数据进行缓冲,提高读取效率。它除了可以使用基类定义的函数,它自己还实现了以下函数:
      • read(char[] cbuf, int offset, int length) :从offset位置开始,读取length个字符到cbuf中,返回结果是实际读取的字符数,到达流的末尾时,返回-1
      • readLine() :读取一个文本行,以行结束符作为末尾,返回结果是读取的字符串。如果已到达流末尾,则返回 null

    使用

    • Reader 是一个抽象基类,不能实例化,但可以用于接口化编程。
    • InputStreamReader需要一个字节输入流对象作为实例化参数。还可以指定第二个参数,第二个参数是字符编码方式,可以是编码方式的字符串形式,也可以是一个字符集对象。

    • FileReader 需要一个文件对象作为实例化参数,可以是File类对象,也可以是文件的路径字符串。

    • BufferReader需要一个字符输入流对象作为实例化参数。

    字符输出流:

    常见的字符输出流有:

    • Writer
    • OutputStreamWriter
    • FileWriter
    • BufferedWriter

    他们的区别与用途:

    • Writer是字符输出流的抽象基类, ,它定义了以下几个函数
      • write(char[] cbuf) :往输出流写入一个字符数组。
      • write(int c) :往输出流写入一个字符。
      • write(String str) :往输出流写入一串字符串。
      • write(String str, int off, int len) :往输出流写入字符串的一部分。
      • close() :关闭流,释放资源。 【这个还是抽象的,写出来是说明有这个关闭功能】
      • flush():刷新输出流,把数据马上写到输出流中。 【这个还是抽象的,写出来是说明有这个关闭功能】
    • OutputStreamWriter可以使我们直接往流中写字符串数据,它里面会帮我们根据字符编码方式来把字符数据转成字节数据再写给输出流,它相当于一个中介\桥梁。
    • FileWriter与OutputStreamWriter功能类似,我们可以直接往流中写字符串数据,FileWriter内部会根据字符编码方式来把字符数据转成字节数据再写给输出流。
    • BufferedWriter比FileWriter还高级一点,它利用了缓冲区来提高写的效率。它还多出了一个函数:
      • newLine() :写入一个换行符。

    使用

    • Writer 是一个抽象基类,不能实例化,但可以用于接口化编程。
    • OutputStreamWriter 需要一个输入流对象作为实例化参数。

    • FileWriter 需要一个文件对象来实例化,可以是File类对象,也可以是文件的路径字符串。

    • BufferWriter

    补充:

    • 上面的一些函数,考虑到效率问题,上面的子类可能会重写基类的函数,但功能基本是不变的。
    • 更多关于字符流的函数与用法可以参考jdk文档。

Java:字节流和字符流(输入流和输出流)的更多相关文章

  1. java 字节流和字符流的区别 转载

    转载自:http://blog.csdn.net/cynhafa/article/details/6882061 java 字节流和字符流的区别 字节流与和字符流的使用非常相似,两者除了操作代码上的不 ...

  2. java 字节流和字符流的区别

    转载自:http://blog.csdn.net/cynhafa/article/details/6882061 java 字节流和字符流的区别 字节流与和字符流的使用非常相似,两者除了操作代码上的不 ...

  3. Java进阶(四十五)java 字节流与字符流的区别

    java 字节流与字符流的区别(转载)   字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢?   实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作 ...

  4. java字节流和字符流,以及java文件操作

    A.首先说字节流:1.字节流在操作的时候不会用到缓冲区(也就是内存)2.字节流可用于任何类型的对象,包括二进制对象3.字节流处理单元为1个字节,操作字节和字节数组.InputStream是所有字节输入 ...

  5. java 字节流与字符流的区别

    字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢?实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作 ...

  6. (转)java字节流和字符流的区别

    转载: http://www.cnblogs.com/dolphin0520/category/361055.html 字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同 ...

  7. Java字节流与字符流基本操作

    在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据时要使用输入流读取数据,而当程序需要将一些数据保存起来时,就要使用输出流. 在java.io包中流的操作主要有字节流.字符流两大类,两类都 ...

  8. java 字节流与字符流的区别 (转)

    字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢? 实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操 ...

  9. Java字节流与字符流

    九.字节流与字符流 9.1 IO的分类 <段落>根据数据的流向分为:输入流和输出流. 输入流 :把数据从其他设备上读取到内存中的流. 输出流 :把数据从内存 中写出到其他设备上的流. 数据 ...

  10. java 字节流与字符流的区别详解

    字节流与字符流 先来看一下流的概念: 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入 ...

随机推荐

  1. NetStandard;.netCore;FX(.netFrameWork)之间引用关系

    .NetStandard;.netCore;FX(.NetFrameWork)之间引用关系   FX引用.NetCore:不通过 NetStandard引用.NetCore:不通过   .NetCor ...

  2. Linux编程 18 安装软件程序(yum工具对软件包安装,删除,更新介绍)

    一.   概述 本篇介绍在linux上见到的各种包管理系统(package management system,PMS)用来进行软件安装,管理,删除的命令行工具.PMS是利用一个数据库来记录各种相关内 ...

  3. FileSync文件同步更新工具

    FileSync是一款文件同步更新工具,它提供了对一个或多个应用的文件进行管理和同步更并功能,基于MD5的文件对比方式可以使管理者轻易地发布需要更新应用文件.FileSync主要模块包括:服务端,CL ...

  4. 【原创】Git删除暂存区或版本库中的文件

    0 基础     我们知道Git有三大区(工作区.暂存区.版本库)以及几个状态(untracked.unstaged.uncommited),下面只是简述下Git的大概工作流程,详细的可以参见本博客的 ...

  5. 基于vue技术的企业移动办公系统的设计与实现

    如何打包: http://www.cnblogs.com/smilehuanxiao/p/7693858.html http://www.cnblogs.com/1314y/p/6207153.htm ...

  6. Java设计模式之《构建者模式》及应用场景

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6553374.html 构建者模式,又称建造者模式,将一部负责对象的构建分为许多小对象的构建 ...

  7. SHELL脚本--多命令逻辑执行顺序

    bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html Linux中可以使用分号“;”.双and号“&& ...

  8. Perl的子程序

    子程序(subroutine) perl中的子程序其实就是自定义函数.它使用sub关键字开头,表示声明一个子程序 子程序名称有独立的名称空间,不会和其它名称冲突 Perl中的子程序中可以定义.引用.修 ...

  9. Redis基础认识及常用命令使用(一)--技术流ken

    Redis简介 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合)和zset(有序集 ...

  10. 结构型---代理模式(Proxy Pattern)

    代理模式的详细介绍 代理模式按照使用目的可以分为以下几种: 远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代表对象.这个不同的地址空间可以是本电脑中,也可以在另一台电脑中.最典型 ...