Java IO小结

IO体系继承图

两个进程间通过网络传输字符串

在计算机底层传输的只有形如01011101这种数字,1字节是由8位bit组成,而字符则是在某种字符集下字节的表现形式,最终都是通过一串01数字表达。当我们谈论字符而忽略字符集时是完全没有意义的,之所以有时不用去关心字符集是因为平台往往是有个默认的字符集。所以在传输字符的时候,发送方和接收方必须要事先约定好字符集。

下面的例子摘自《Java特种兵》书籍的第四章

例如发送2个汉字,用UTF-8编码发送后会占用6个字节,对方若知道传来的数据是UTF-8编码,便知道这6个字节代表什么汉字,就自然能正确得到char字符了。但是如果对方用GBK来编码,则可能会认为有3个字符,若按照每2个字节计算一个字符,得到的3个字符自然不是需要传递的2个汉字字符。假如此时意识到自己的编码错误了,通过得到的3个字符的字符串调用get-Byte(“GBK”)还可以还原6个字节,然后通过这6个字节再用new String(byte[],“UTF-8”)得到实际的两个汉字。真的是这样吗?要知道这是偶然的,不是必然的,因为UTF-8转换出来的6个字节,当按照每2个字节组成编码时,这个编码未必在GBK的编码范围内,若不在GBK的编码范围内,就可能会用一个“?”或其他字符来代表,由于“?”本身也是一个字符,当再次调用get-Byte(“GBK”)时得到的对应字节就是“?”对应的字节,而不是原来字符的字节,有可能都不再是6个字节了。换句话说,这样的情况是永远无法转换回来的。

字节流和字符流的关系
Reader/Writer内在的实现是通过sun.nio.cs.StreamDecoder、sun.nio.cs.StreamEn-coder来对字符集进行处理,最终还是通过字节来完成发送和接收的。

read()的小疑惑

InputStream.read()方法返回一个int值,表示从流中读取的一个字节。我们知道byte类型的取值范围是:-128到127,但是read方法返回值的范围是0 - 255(另外返回-1表示流中没有可读字节)。
为什么要这样设计呢?其中一个原因是因为字符集的码表都是用非负数来表示的。
那如何进行转换呢?在BufferedInputStream中,其read()方法是这样写的

public synchronized int read() throws IOException {
    if (pos >= count) {
        fill();
        if (pos >= count)
            return -1;
    }
    return buf[pos++] & 0xff;
}

其中buf是byte数组,可以看到通过buf[pos++] & 0xff将字节的范围转移到0 - 255。

按用途分类流

字节输入流 字节输入流 字符输入流 字符输出流
基础 InputStream OutputStream Reader InputStreamReader Writer OutputStreamWriter
数组 ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter
文件 FileInputStream RandomAccessFile FileOutputStream RandomAccessFile FileReader FileWriter
网络 SocketInputStream URL HttpURLConnection Socket SocketOutputStream URL HttpURLConnection Socket
管道 PipedInputStream PipedOutputStream PipedReader PipedWriter
缓冲 BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter
Filtering FilterInputStream FilterOutputStream FilterReader FilterWriter
解析 PushbackInputStream StreamTokenizer PushbackReader LineNumberReader
String StringReader StringWriter
Data DataInputStream DataOutputStream
格式 PrintStream PrintWriter
序列化 ObjectInputStream ObjectOutputStream
Utilities SequenceInputStream LineNumberInputStream LineNumberReader

扩展阅读
Java IO Tutorial

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

推荐阅读更多精彩内容