我学 Java IO

说起来,我接触 Java 是从大一下学期开始的,通过逐步学习接触到了 Java IO 这个很重要的模块,同时也是让我很头疼的一个模块,好像一直都没怎么学会。在我的脑子里,一直都是那种,这么多相关的类,怎么能记住啊。再加上,后来转战 Android 就更少有直接使用 Java IO 去操作文件的机会。一个偶然的机会,我学到了可以从另一种视角看 Java IO,突然觉得,Java IO,并不难。现在,我来记录并分享一点自己的经验。

如果是讲操作文件的 API 的话,那估计得写的老长,事实上,我对 Java IO 相关的 API 并不太熟,而且我也不打算讲。在这里我可能是从另一种我觉得是站在全局的角度去看 Java IO。

通常的,我们使用 Java IO 都是为了去对文件进行操作,或读或写。读:从磁盘、网络等渠道将文件内容读入到内存中;写:通过将内存中的数据写入到磁盘、网络等进行持久化保存。

Java Io

以前啊,我就光想着 Java IO 就是这么读文件,写文件,也没什么的嘛。不就是对文件的操作嘛,没什么可讲的的,现在我不这么想了。现在怎么想呢?我换了一种思路。

我们使用 Java IO 写东西,写的是什么?是字符串,字符串是什么?是字符数组组成的一种的对象,什么是字符?字符就是可以通过字节码的形式表现出来一种东西。而字节码就是 OutputStream 以及 InputStream 直接能进行操作的东西,那什么是它们不是直接操作的?不就是字符串、字符数组嘛。可是我们在写程序的时候,谁还记得这个字符串的字节码是什么,那个字符的字节码是啥。我们都是直接操作字符串以及少部分情况操作字符数组的。那怎么办?

String To byte

有的人说,通过各种转换就可以对应的字节码,然后进行操作。事实上就是这样的,Java 提供给我们的方法也是如此,通过各种转换得到可以操作 String 或是字符数组,然后进行操作。比如,OutputStreamWriter 就可以使用 OutputStreamWriter.write(String); 来直接操作字符串进行写入文件,还有通过 BufferedReader 就可以使用 String lineString = bufferedReader.readLine() 来直接进行读取一行文字。可是总一些我们可以从另一种角度看的东西。

仔细看一下,第二幅图,没什么啊,不就是数据在他们之间进行转换吗,有什么的?是这样的,但是还可以有另一种看法,字符串就是另种形式的字符数组,而字节数组就是另一种形式的字符数组。他们还是自己本身,只不过穿上了一件 “衣服” 而已。穿上了这身衣服,你以为他变了,从字符串 String 变成了字符数组 char[] 实际上,他还是 String ,只是不同的表现形态而已。没有什么不同,他还是他,只是你需要看穿这件 “衣服”。

那你说,既然数据本身都没有变化,只是穿了件衣服,那为什么 Java IO 的操作,显得那么的麻烦?因为,为了方便处理,也给处理过程穿上了衣服。OutputStream 只能处理字节数组,而包裹了一层 OutputStream 的 OutputStreamWriter 就能直接的操作 char[] 和 String。

好麻烦啊,就不能有一个直接能用来操作字符串的对象吗,每回写文件读写的时候,都得写好几个对象,烦死了。别烦啊,这样做是有这样做的理由的。就拿读操作(InputStream)来说吧,我曾天真的以为读操作只有一个来源就是,文件(FileInputStream)。后来才发现,竟然有 ByteArrayInputStreamObjectInputStreamPipedInputStreamStringBufferInputStream 等等(只列出部分,全部的都 在这 呢。他们分别处理字节数组、被序列化的对象、线程间的输入流以及来自 StringBuffer 的输入。对应的还有写操作(OutputStream)整体来说,虽然比 InputStream 少,但是也有好几个呢,ByteArrayOutputStreamFileOutputStreamFilterOutputStreamObjectOutputStreamPipedOutputStream

如果这么多种输入或是输出方式,都要能处理 String、long、int 这种,或是再兼容一些其他方便我们程序员操作的方法,那类就太多了,想想一下,一个 FileInputStream 就可能变成了 StringFileInputStream、LongFileInputStream、IntegerFileInputStream ,想想就觉得可怕。所以,Java 采用了穿 “衣服” 的形式,让程序员通过对数据穿上不同的衣服,从而达到操作不同数据类型的效果。

image

FileInputStream 只能读出字节数组,InputStreamReader 可以读出字符数组,通过不同的对象进行转换,就能读出或是写出不同形式的数据。而且 FileInputStream 可以作为 InputStreamReader 的提供者,这样的话,就能应对足够复杂的场景,只要给当前的对象穿上另一件"衣服"就能摇身一变成为你想要的结果。

感觉很神奇啊,只要是 InputStream 相关的类,都可以作为生成下一个 xxInputStream 对象输入,只要是一个 OutputStream 相关的类都可以作为生成下一个 xxOutputStream 对象的输入。其实啊,知道细节之后就不会觉得神奇了,只会觉得设计的很巧妙。

FilterOutputStreamFilterInputStream 这两个是关键,他们俩分别继承自 OutputStream 和 InputStream,同时又有非常多的子类,就是通过这些子类来实现各种转换,什么线程的输入做到输出字符数组、被序列化的对象输出字符串等等。

FilterOutputStream 子类:

  • BufferedOutputStream
  • CheckedOutputStream
  • CipherOutputStream
  • DataOutputStream
  • DeflaterOutputStream
  • DigestOutputStream
  • InflaterOutputStream
  • PrintStream

FilterInputStream 子类:

  • BufferedInputStream
  • CheckedInputStream
  • CipherInputStream
  • DataInputStream
  • DeflaterInputStream
  • DigestInputStream
  • InflaterInputStream
  • LineNumberInputStream
  • ProgressMonitorInputStream
  • PushbackInputStream

这些子类固然是很重要的,便于操作不同的数据类型,同样重要的还有 Reader、Writer。这两个类并不继承 InputStream 与 OutputStream 但通过他们的子类,也同样能实现更简单的文件读写。比如 OutputStreamWriter、InputStreamReader。都可以直接对 String 进行操作。再搭配上 InputStream 和 OutputStream 那一大家子,真的是可以对文件可以为所欲为了。

对了,还一个 Buffer,它直译过来是缓冲的意思,干什么用的呢?是这样的,磁盘的读取或写入的速度并没有像直接操作内存那样快,所以需要一个缓冲的东西用来缓解双方操作上的时间差,比如在写的时候,可以先写到缓冲区,然后再把缓冲区的数据一点点写到磁盘上。或者说,从磁盘读数据的时候,先读一些,读到缓冲区,等读的东西,够多了,然后再一起写入到内存中去。

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

推荐阅读更多精彩内容