Java字节流 字符流(三)

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

代码分析

看下面这段代码:

 public class JavaEncode {

    public static void main(String[] args) throws IOException {
        
       // test 1
        InputStream inputStream = new FileInputStream(new File("demo.txt"));
        byte[] bytes = new byte[6];
        inputStream.read(bytes);
        System.out.println(HexUtil.encodeHex(bytes));

        String utf8Str = new String(bytes, "gbk");
        System.out.println(utf8Str);

       // test 2
        inputStream = new FileInputStream(new File("demo.txt"));
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "GBK");
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String cs = bufferedReader.readLine();
        System.out.println(cs);

    }
}

其中demo.txt中存储的文本为:


image.png

另外文件编码格式是UTF-8。

输出的结果为:

e4b8ade59bbd
涓浗
涓浗

其中e4b8ade59bbd为“中国”两个汉字的UTF-8编码,第二行和第三行为乱码,两次输出的乱码是一样的。

对于test 1

  • 首先创建了一个demo.txt文件的输入流(类似于一个管道)
  • 然后从输入流中读取文件的字节流。根据输出的结果,可以看出,test 1是以UTF-8编码格式,将“中国”两个汉字的字节读入字节数组的
  • 【String utf8Str = new String(bytes, "gbk");】debug一下,看看utf8Str中存的字符数组是什么



    它想将字符以UTF-8编码格式获取的字节数组再以GBK编码的形式转化为字符。
    GBK是定长编码,UTF-8是不定长编码,这一转肯定是要出问题的。“中国”两个字符以UTF-8编码,是长度为6的字节数组,GBK字符字节长度为2,所以变成了三个字符,但是在JVM中,都是Unicode字符编码来表示字符的,所以JVM又将三个GBK字符编码转换成了Unicode编码,存在JVM内存中,才有了utf8Str上图中的情况。

对于test 2,

  • 【 inputStream = new FileInputStream(new File("demo.txt"));】建立字节输入流
  • 【 InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "GBK");】InputStreamReader是字节流向字符流转换的桥梁,可以指定编码格式。
  • 【 BufferedReader bufferedReader = new BufferedReader(inputStreamReader);】 BufferedReader是字符流的一种实现方式,后面会介绍。
  • 【String cs = bufferedReader.readLine();】按行读取文本。字符串cs中的字符数组存储的是什么呢?


    image.png

    这行代码在读取文本中的信息的时候,应该也是经历了如下步骤

  1. 获取UTF-8编码格式字节数组 bs
  2. 根据GBK编码,将bs转化为GBK字符
  3. 将GBK字符转化为其对应的Unicode编码,于是有了上图cs的情况。

从上面的两个test可以看出, test 1可以操作到字节级别,这个就叫做字节流,test 2操作最小的也是一个Unicode字符,这个叫做字符流。从我们创建字符流对象的过程,可以知道,字符流其实是对字节流的封装,只不过字符流一次会操作一个Unicode字符。
另外,字节流处理的范围更加大,例如图片、音频等,我们可以获取他们的字节流,但是它们有自己的编码规则,无法转化为我们的字符。

Java I/O编码系统

  • 面向字节流的InputStream和OutputStream
  • 面向字符流的Reader 和 Writer

字节流的InputStream和OutputStream是一切的基础,实际总线中流动的只有字节流。Java中负责从字节流向字符流解码的桥梁是:
InputStreamReader和OutputStreamWriter,可以指定以什么编码格式读取或写入。

Java中的字符流处理的最基本的单元是Unicode码元(大小2字节),它通常用来处理文本数据。所谓Unicode码元,也就是一个Unicode代码单元,范围是0x0000~0xFFFF。在以上范围内的每个数字都与一个字符相对应,Java中的String类型默认就把字符以Unicode规则编码而后存储在内存中。然而与存储在内存中不同,存储在磁盘上的数据通常有着各种各样的编码方式。使用不同的编码方式,相同的字符会有不同的二进制表示。实际上字符流是这样工作的:

  • 输出字符流:把要写入文件的字符序列(实际上是Unicode码元序列)转为指定编码方式下的字节序列(OutputStreamWriter指定的编码,如果没有指定,则按照操作系统默认),然后再写入到文件中;
  • 输入字符流:把要读取的字节序列按指定编码方式解码为相应字符序列(按照InputStreamReader指定的编码,先编码,再转码为Unicode码元序列)从而可以存在JVM内存中。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容