Java开罐头——I/O流官方指南之字符流Character Streams

收纳进此专辑:I/O流官方中文指南系列概述及索引

大部分内容来自 The Java™ Tutorials 官方指南,其余来自别处如ifeve的译文、imooc、书籍Android面试宝典等等。
作者: @youyuge
个人博客站点: https://youyuge.cn

一、什么是字符流

什么又是字节流?它们之间又有什么关系?请先仔细阅读我的这篇,对字符编码有个彻底的认知。

Java开罐头——字符编码最全解析

看完之后,你应该理解地比较透彻了,我个人的总结理解如下

  • 首先,计算机中文件存储是二进制存储字节,CPU也只能读取二进制也就是0和1(你问为啥?百度一下),但是如何0和1怎么表示我们的英文字母和汉字呢?
  • 为了能用二进制来表示我们生活中的字符,我们做了人为的规定,也就是编码集,但是编码的规定是人定的,是有很多种的,比如我们对一个汉字编码,同一个汉字在不同的规定下是不一样的:

汉字“” --------> 5C24 (UTF-8编码方式)
汉字“” --------> D3C8 (GBK编码方式)

  • 所以,我们用UTF-8格式写了一个txt文件,实际计算机会将我们的字符编码成二进制的0和1存储起来。当我们用UTF-8格式打开它的时候,文本编辑器会根据UTF-8的转换规则,把二级制的一大堆0和1解码成我们人看的懂的字符,并且显示出来。

  • 所谓的打开txt乱码也就很好解释了, 我们用UTF-8的编码准则,去打开一个用GBK准则写的txt,就会乱码。通俗的说,两个编码准则其实是对一大堆二进制0和1的不同翻译罢了。

  • 更通俗的一个例子,我有一句中文“鱿鱼最好吃”,转换成字母(编码):you yu zui hao chi,把它存储起来,发给别人。别人打开文件,看到“you yu zui hao chi”,他用英语这个去翻译(解码),翻译不出来,不明所以。所以他又用中文这种解码去翻译,发现这不就是拼音吗,大概就知道了意思。在这个例子里,中文就是一个编码准则(如GBK),英文也是一种(如UTF-8),而字母就是字节,底层的二进制。

二、字符流官方定义Character Streams

The Java platform stores character values using Unicode conventions. Character stream I/O automatically translates this internal format to and from the local character set. In Western locales, the local character set is usually an 8-bit superset of ASCII.

Java平台使用Unicode标准去存储字符的值。字符流I/O自动把这种内在的形式转换成本地字符编码集。在西方,本地字符集通常是ASCII的8比特的超集。

三、使用字符流Using Character Streams

All character stream classes are descended from Reader
and Writer
. As with byte streams, there are character stream classes that specialize in file I/O: FileReader
and FileWriter
. TheCopyCharacters
example illustrates these classes.

所有的字符流的类都是从Reader和Writer继承而来。和字节流一样,有专门对文件读写的字符流的类: FileReader and FileWriter。如下是用字符流复制文件:

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopyCharacters {
    public static void main(String[] args) throws IOException {

        FileReader inputStream = null;
        FileWriter outputStream = null;

        try {
            inputStream = new FileReader("xanadu.txt");
            outputStream = new FileWriter("characteroutput.txt");

            int c;
            while ((c = inputStream.read()) != -1) {
                outputStream.write(c);
            }
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }
}

CopyCharacters is very similar to CopyBytes. The most important difference is that CopyCharacters uses FileReader and FileWriter for input and output in place of FileInputStream and FileOutputStream. Notice that both CopyBytes and CopyCharacters use an int variable to read to and write from. However, in CopyCharacters, the int variable holds a character value in its last 16 bits; in CopyBytes, the int variable holds a byte value in its last 8 bits.

  • 复制字符和复制字节很像。最重要的不同点是,复制字符用的是FileReader and FileWriter 而非FileInputStream and FileOutputStream。

  • 注意,复制字节和复制字符都用了一个int整型变量(4字节)来读写。但是,复制字符,int只有最后2字节有数据,前面2字节都是0,因为Java默认是UTF-16编码。而复制字节,每次一个字节,所以int变量只有最后一个字节有数据。

四、字符流使用了字节流

Character streams are often "wrappers" for byte streams. The character stream uses the byte stream to perform the physical I/O, while the character stream handles translation between characters and bytes. FileReader, for example, uses FileInputStream, while FileWriter uses FileOutputStream.

字符流是对字节流的包装。字符流使用字节流来操作物理I/O,而字符流是处理字符和字节直接的转换。FileReader类使用了FileInputStream,而FileWriter使用了FileOutputStream。

There are two general-purpose byte-to-character "bridge" streams: InputStreamReader
andOutputStreamWriter
. Use them to create character streams when there are no prepackaged character stream classes that meet your needs. The sockets lesson in the networking trail shows how to create character streams from the byte streams provided by socket classes.

有两种通用的字节到字符的“桥梁”流:InputStreamReader OutputStreamWriter 。当没有满足你要求的预包装的字符流的时候,使用它们来创建字符流吧!在网络指南中的socket课程里,展示了如何用提供的socket类来把字节流转换成字符流。

五、面向行的I/O

Character I/O usually occurs in bigger units than single characters. One common unit is the line: a string of characters with a line terminator at the end. A line terminator can be a carriage-return/line-feed sequence ("\r\n"), a single carriage-return ("\r"), or a single line-feed ("\n"). Supporting all possible line terminators allows programs to read text files created on any of the widely used operating systems.

有时候我们需要按照一行一行来读入或者输出。通常,一行被定义为:一个字符串,以一个行终止符结尾。行终止符可以是回车+换行 ("\r\n")(windows下的换行符),可以是一个单回车符("\r"),或者是单换行符("\n")(mac OSX系统的换行符)。这样一来,各种不同系统创建的文本文件,我们都能使用这种方式来正确地获取所谓的一行。

注意:println方法是在末尾加上当前操作系统的换行符,所以为了保证跨平台性,Java中的换行符不能简单地写“/r/n”,而必须用:

 //java写的根据系统平台得到换行符CRLF
 String lineSeparator = System.getProperty("line.separator", "/n");
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容