[笔记]Java IO之InputStream和OutputStream

InputStream和OutStream是java.io包中面向字节操作的两个顶层抽象类,所有关于java同步IO字节流的操作都是基于这两个的。

什么是流?

《O'Reilly-Java Io》中是这么解释的:

A stream is an ordered sequence of bytes of undetermined length. Input streams move bytes
of data into a Java program from some generally external source. Output streams move bytes
of data from Java to some generally external target. (In special cases streams can also move
bytes from one part of a Java program to another.)

流是一个不确定长度的有序字节序列。输入流从外部资源将数据字节移动到Java程序中。输出流从Java程序中将数据字节移动到外部目标。(特殊的情况也可以将字节从java程序中一部分移动到另一部分)

流从哪里来?

通常流来自于:
1、网络
2、文件
3、java内部程序

InputStream(输入流):

InputStream作为java中用于读取流中字节的顶层抽象类,定义了一些方法:

public abstract int read() throws IOException
public int read(byte b[], int off, int len) throws IOException
public int read(byte b[]) throws IOException {
        return read(b, 0, b.length);
}

有三个read方法用来读取字节:
1、第一个抽象方法交由子类来实现,读取一个无符号字节,由于java本身没有无符号字节的基本类型,所以用int作为返回值。当返回-1时表示到了流的结尾,这也是需要返回int的原因之一(因为带符号的byte有可能是-1)

2、
作用: 从流中读取字节数组,通常一个一个字节的读效率相当低下,可指定数组中开始的偏移位置off,长度len
参数: 保存字节的字节数组、偏移量、长度。
返回值: 实际读到的字节数(-1为末尾)
默认的实现依赖于第一个抽象方法,就是循环调用读取一个无符号字节。所以效率不是很高,通常会有的子类以更高效的方式来重写。

3、
作用: 从流中读取字节数组,通常一个一个字节的读效率相当低下。
参数: 保存字节的字节数组
返回值: 实际读到的字节数(-1为末尾)
默认的实现依赖于第二个方法,仅仅是用read(b,0,b.length)来实现,重写这个方法的子类相对较少。

public int available() throws IOException

作用: 从流中立刻能够获取到的字节数。
返回值: 能够读取到的字节数(没有会返回0,到流的末尾也会返回0)

public long skip(long bytesToSkip) throws IOException

作用: 从流中跳过一定字节不读,通常跳过比读取后不处理快(比如文件流,只是指针的移动)。
参数: 期望跳过的字节数
返回值:实际跳过的字节数(遇到末尾返回-1)

public void close() throws IOException

作用: 用完流之后,关闭流,但并不是所有的流都需要关闭,比如说System.in

关闭流的最佳实践:
1、在finally中关闭

.
    InputStream in = null;
    try {
        in = new ...;
        ...
    } catch(IOException e) {
        ...
    } finally {
        try {
            if (in != null) {
                in.close();
            }
        } catch(IOException e) {
    
        }
    }

2、java7支持try-with-resources方式关闭流,实现了java.lang.AutoCloseable接口的对象支持用这种方式

.
    try (InputStream in = new ....){
        ...
    } catch(IOException e) {
        ...
    }

标记和重置:

public synchronized void mark(int readLimit)
public synchronized void reset() throws IOException
public boolean markSupported()

有时候你读取一些字节后希望返回到之前的位置重新读,这几个方法就是用来做这件事。

public boolean markSupported()

作用: 判断当前流是否支持标记
返回值: 当前流是否支持标记
如果当前流不支持标记,执行reset()方法将抛出一个IOException异常,而mark()方法不会做任何操作

public synchronized void mark(int readLimit)

作用: 将读取的位置标记在当前位置。
参数: 最大可阅读超过标记位置的字节数(只要没有阅读超过readLimit字节数,就可以重置回去)
在同一时刻,只能有一个标记,再设置会覆盖
java.io中只有BufferedInputStreamByteArrayInputStream支持标记。但是其他的过滤流连接到这两个上也支持标记。

OutputStream(输出流):

OutputStream作为java中用于向流中写字节的顶层抽象类,定义了一些方法:

public abstract void write(int b) throws IOException
public void write(byte[] data, int offset, int length) throws IOException
public void write(byte[] data) throws IOException

有三个write方法用来向流中写字节:

1、第一个是抽象方法交由子类实现,向流中写入一个无符号字节(0-255),如果超过255只会取低八位的字节。

2、作用: 向流中写入字节数组,可以指定数组中起始的偏移位置和长度。
参数: 写入的字符数组、起始的偏移位置、长度
默认的实现是循环调用第一个方法一个一个写入,但是效率极其低下,子类一般会有更高效的方式

3、作用: 向流中写入字节数组
参数: 写入的字符数组
默认的实现是调用第二个write()方法write(b, 0, b.length);

public void flush() throws IOException

作用: 许多输出流增加一个缓冲区来提升性能,当缓冲区写满之后才会发送数据,而flush()方法可以强制清空缓冲区发送数据,如果不刷新则有可能导致数据丢失。通常PrintStreamprintln()方法会自动flush()

public void close() throws IOException

作用: 当用完输出流之后,将流关闭,关闭的同时也会flush()

无处不在的IOException:

IOException是受检异常,在程序中必须被声明。
IOException存在的意义是因为操作系统中的‘输入’和‘输出’是不可靠的,操作系统层级发生的异常是不受程序控制。

子类

java.io包中常用的子类:

其它包中还有一些类。

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

推荐阅读更多精彩内容

  • tags:io categories:总结 date: 2017-03-28 22:49:50 不仅仅在JAVA领...
    行径行阅读 2,166评论 0 3
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,559评论 18 399
  • 在经过一次没有准备的面试后,发现自己虽然写了两年的android代码,基础知识却忘的差不多了。这是程序员的大忌,没...
    猿来如痴阅读 2,821评论 3 10
  • 《秋的姿态》 秋日清晨,乳白的轻雾像轻纱一样笼罩在田野上,晨风吹来,那纱轻轻舞动,霞光把轻雾染的坨红,苗儿也变得晶...
    秋秋的深阅读 230评论 6 11
  • 坐 静坐 处子般娴雅 掠过无声 悄然绽放 行 行走 任性无压力的释放 可举杯揽月 又可嬉戏耍闹 …… 此一生 肩负...
    格小主阅读 320评论 0 0