3句话帮你搞定Java I/O底层原理之一(字符流、字节流及其区别)

3句话帮你搞定Java I/O底层原理之一(字符流、字节流及其区别)
文章图片

Java中字符流与字节流 3句话帮你搞定Java I/O底层原理之一(字符流、字节流及其区别)
文章图片

什么是流?

  • Java中的流是对字节序列的抽象。
  • 数据在两设备间的传输称为流,流的本质是数据传输。
  • 程序中的输入输出都是以流的形式保存的,流中保存的实际上全都是字节文件。
我们可以想象有一个水管,只不过现在流动在水管中的不再是水,而是字节序列。
流是一组有顺序的,有起点和终点的字节集合。
即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
什么是字符和字节?
  • 1 byte = 8 bit
  • 1 char = 2 byte = 16 bit (Java默认UTF-16编码)
  • 3句话帮你搞定Java I/O底层原理之一(字符流、字节流及其区别)
    文章图片
字节流
  • InputStream和OutputStream是所有字节流的基类,是一种抽象类。
  • Java中的字节流处理的最基本单位为单个字节,它通常用来处理二进制数据。
字节流的使用
InputStream类与OutputStream类均为抽象类,我们在实际使用中通常使用Java类库中提供的它们的一系列子类。下面我们来介绍下Java中的字节流。
InputStream
方法 功能描述
void close() 关闭输入流
int read() 从输入流中当前位置读取一个字节的二进制数据,以此数据为低位字节,补足16位的整型量(0~255)后返回,若输入流中当前位置没有数据,则返回-1
int read(byte b[]) 从输入流当前位置连续读取多个字节并保存到数组中,返回所读取的字节数
int read(byte b[], int offset, int len) 从输入连当前位置连续读取len长的字节,从数组offset位置处开始存放,返回所读取的字节数
int available() 返回输入流中可以读取的字节数
long skip(long n) 跳过字节流中n个字节,此方法有可能失效
boolean markSupported() 判断输入流是否支持标记
void mark(int n) 标记输入流的当前位置, 参数n表示读取n个字节前标记有效
void reset() 将读取位置返回到对此输入流最后调用mark()方法的位置
另外,字节流在默认情况下是不支持缓存的,这意味着每调用一次方法都会请求操作系统来操作一个字节,这往往会伴随着一次磁盘IO,因此效率会比较低。
OutputStream
方法 功能描述
void close() 关闭输出流
void flush() 强制清空缓存区并向外设输出数据
void write(int b) 将参数b的低位字节写入输出流
void write(byte b[]) 将数组b写入输出流
void write(byte b[], int offset, int len) 将数组b第offset位置开始,写入len个字节到输出流

字符流
  • Java中的字符流处理的最基本的单元是Unicode码元(大小2字节)
Unicode码元,也就是一个Unicode代码单元,范围是0x0000~0xFFFF。在以上范围内的每个数字都与一个字符相对应,Java中的String类型默认就把字符以Unicode规则编码而后存储在内存中。
字符流的使用
Reader
  • 输出字符流:把要写入文件的字符序列(实际上是Unicode码元序列)转为指定编码方式下的字节序列,然后再写入到文件中。
方法 功能描述
void close() 关闭该流并释放与之关联的所有资源。
int read() 读取单个字符
int read(char[] cbuf) 将字符读入数组
int read(char[] cbuf, int off, int len) 将字符读入数组的某一部分
int read(CharBuffer target) 试图将字符读入指定的字符缓冲区
Write
  • 输入字符流:把要读取的字节序列按指定编码方式解码为相应字符序列(实际上是Unicode码元序列从)从而可以存在内存中。
方法 功能描述
void close() 关闭此流,但要先刷新它。
void flush() 刷新该流的缓冲
void write(char[] cbuf) 写入字符数组
void write(char[] cbuf, int off, int len) 写入字符数组的某一部分
void write(int c) 写入单个字符
void write(String str) 写入字符串
void write(String str, int off, int len) 写入字符串的某一部分
【3句话帮你搞定Java I/O底层原理之一(字符流、字节流及其区别)】3句话帮你搞定Java I/O底层原理之一(字符流、字节流及其区别)
文章图片

字符流与字节流的区别
  • 字节流默认不使用缓冲区;字符流使用缓冲区。
  • 字节流操作的基本单元为字节;字符流操作的基本单元为Unicode码元。
  • 字节流通常用于处理二进制数据,实际上它可以处理任意类型的数据,但它不支持直接写入或读取Unicode码元;字符流通常处理文本数据,它支持写入及读取Unicode码元。

    推荐阅读