Java 流

Java 流

什么是流

流是一个相对抽象的概念,所谓流就是一个传输数据的通道,这个通道可以传输相应类型的数据。进而完成数据的传输。这个通道被实现为一个具体的对象。

字符流和字节流

抽象类

  • 处理字节:InputStream OutputStream

  • 处理字符:Reader Writer

Java中字符是以Unicode形式存储的,一个字符占用两个字节,然而InputStream和OutputStream都是以字节形式读取或写出数据的,会将一个字符拆分成两个字节来读写这样会造成乱码

基础用法

在InputStream 和 Reader抽象类中都有一个抽象方法 abstract int read(),这个方法将会读入一个字节或字符,当到达输入数据块的末尾的时候返回-1,所有的输入流只要覆盖这个方法,完成具体的功能。

在OutputStream 和 Writer抽象类中都有一个抽象方法 abstract void write(int b),这个方法将会象某一个输出位置写一个字节或者字符。所有的输出流只覆盖这个方法,完成具体的输出功能。

read()和write()方法都是阻塞方法,当一个流不能被立即访问或者字节不能被成功的读出或写入的时候,当前线程将进入阻塞态直到字节确实被读入或者被写出。这样的设置保证了数据的安全性。

流的结构

输入流与输出流层次结构

输入流与输出流层次结构

Reader和Writer的层次结构

Reader和Writer的层次结构

字符集与编码

ASCII

对于西方来说,用不到字符,字节就够了。26个字母外加几个常用的符号。256个码位就够了。这就是我们常见的ASCII码表

ASCII码表

ISO/IEC 8859-1

西方世界不光英语,还有小语种。每个国家都可以定义属于自己语言的特殊编码标准,而且大小一样不超过256。因为ASCII码本身还有空位。所以就衍生出了ISO/IEC 8859-n国际标准化组织定义的一系列8位字符集。比如ISO/IEC 8859-1就是法语,芬兰语所用的西欧字符集。如下图。

ISO/IEC 8859-1

Unicode

在出现Unicode之前,几乎每一种文字都有一套自己的编码方式。同一段“字节流”,在美帝可能是"hello world",到我们天朝就变成“锟斤拷” ,“烫烫烫”了。所以“Unicode”可谓大势所趋。它的理念非常简单:全世界每个不同语言的不同字符都统一编码,全球通行。

最初,每个字符占用2个字节,总共65536(2的16次方,即一个字符)个字符空间。后来又了附加字符集。目前Unicode收录的字符规模大概在12万左右。

UTF-16

编码里最容易搞混的一件事就是:Unicode只是一套符号的编码。但计算机具体怎么读取这套编码,又是另外一件事。

比如既然Unicode常规字符集占用2个字节,系统可以每次老老实实读取两个字节。然后用一个特殊符号告诉系统某个字符属于附加字符集,需要再往后读2个字节。比如说Java系统默认的UTF-16就是就是这样编码解码的。

UTF-16

UTF-8

但上面UTF-16的缺点也很明显:就是所有英语字符“I am”也被迫用2个字节来编码。

考虑到英语是使用最广泛的语言,用2个字节为1字节信息编码,浪费了内存空间。最好是让英语保持ASCII的编码,用1个字节。汉字等其他字符才用2个或更长的字节表示。

这里就涉及到一个技术问题:怎么让系统知道一个字符是用1个还是2个还是3个字节编码的呢?这就是UTF-8做的事。

如下图所示,这里UTF-8可变长编码用到了一个小技巧:用几位冗余信息告诉系统,当前字符有没有结束,是不是还需要继续往下读下一个字节。

UTF-8冗余位

可以看到如果一个字节是以“0”开头的,说明是一个ASCII字符,只占一个字节。如果是“11”开头的,说明这个字符占用多个字节。后续每个“10”打头的字节都是这个字符的一部分。

总结

总而言之,一切都是字节流,其实没有字符流这个东西。字符只是根据编码集对字节流翻译之后的产物。

  • 11
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值