java io -- InputStream
来源:互联网 发布:怎么切换mac系统 编辑:程序博客网 时间:2024/05/19 06:50
上篇文章java io-流简单介绍了流的概念,本文我们就关注于字节流。
从java字节流说起,java的字节流有两种:输入流和输出流,我这里只分析输入流,输出流与输入流类似,只是方向相反。
输入流,顾名思义,就是我们输入我们程序的字节流,也就是如果我们的程序需要输入时,我们从流中读取。
输入流是一个抽象的概念,当我们读取文件时,就把文件抽象成一个输入流,当我们读取字节数组时,可以把这个字节数组当成输入流,当我们从网络读取数据时,可以把socket当成一个输入流(网络流这里只是提及,本文暂不涉及,会在网络部分讲述)。
我的习惯,废话少说,先上类图。
图1 InputStream类图
图1是输入流的整体类图,由于我们日常用到的输入流就是那么几个,所以如果有遗漏,还请参照oracle官网。
从类图中可以看出,InputStream算是一个top class,首先需要注意的是这个类是一个抽象类。为了能够更好的理解输入流,我先给大家展示一下InputStream的定义和结构。
public abstract class InputStream implements Closeable { .......// 方法的定义见下图}
好的,从上面的代码和图中,得知Inputstream是一个抽象类,现在我们深入几个重要的方法,进行探究。
1 read()
public abstract int read() throws IOException;
read()函数,这就是这个类的灵魂函数了,作为一个输入流,最重要的就是读!
在jdk中的源码中,有read方法很详细的注释。
这个方法用来读取inputstream中的下一个字节!如果没有数据返回-1,如果有,就以int的方式返回,为什么返回一个int呢?以为一个字节一共8个bit,用数字0-255就可以表示,深入一点呢,就是一个int共四个字节,用来放这读取出来的一个字节必然是够了。
而且还有一点需要强调,在java的注释中,有这么一句:
// This method blocks until input data is available
也就是说,这个方法是一个block的方法,如果你正在看java的nio或java的socket,就会知道,这个block是一个很重要的特性。当然如果你只是读读文件,可以先不用理会这个特性。
read()方法是一个抽象方法,这些特性其实也只是规定罢了,真正的实现都是要在子类中实现的,我们之后再说。
2 read(byte b[], int off, int len)
这个方法的源码如下:
public int read(byte b[], int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } else if (off < 0 || len < 0 || len > b.length - off) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } int c = read(); if (c == -1) { return -1; } b[off] = (byte)c; int i = 1; try { for (; i < len ; i++) { c = read(); if (c == -1) { break; } b[off + i] = (byte)c; } } catch (IOException ee) { } return i;}
从上述源码中,我得出如下几点结论
1)这个read()方法是一个重要的方法,在我们的实际工作中,不可能是一个字节一个字节去读取,一定是一次读取一批,这时,java为我们封装了一个读取多个字节的方法,从源码中可以看出,这个方法其实也时循环去读取数据。
2)这是一个非抽象方法,InputStream的子类可以直接调用这个方法,我个人认为这算是一个template模式。
3)这个方法的参数是指从流中欲读取len长的数据,置于以offset开头的数组中。
如果读取流到达末端,即时返回。最后返回的是实际从流中读取的数据长度。
4)这个方法有个需要注意的地方:
如果数组的长度不够,会报IndexOutOfBoundsException异常。
3 read(byte b[])
这个方法源码如下:
public int read(byte b[]) throws IOException { return read(b, 0, b.length);}
这个方法是从流中读取数据,直接读满这个数组(如果流中有足够的数据),并返回实际读取的字节数。
好的,InputStream说了这么多,应该对字节流有了一个起码的认识了,由于输入流是一个整体的抽象,一个文件可以作为一个字节流,一个字节数组也可以作为一个字节流。因此java对每一种输入流都做了一个子类,比如ByteArrayInputStream就可以把一个字节数组作为一个输入流,当然了这个字节数组一定是在内存中了。
如果想读取磁盘中的文件,这时就需要一个FileInputStream了,由于在日常的开发中,读取文件是常有的事,因此我们下一节就对FileInputStream做一个介绍。
- java io InputStream Reader
- Java IO 操作 InputStream
- Java.IO.InputStream-OutputStream
- java io InputStream Reader
- java io之InputStream
- java.io.InputStream
- java IO之InputStream
- import java.io.InputStream;
- Java IO: InputStream
- Java IO - InputStream&OutputStream
- Java IO : InputStream、Reader
- java io -- InputStream
- java.io.InputStream
- 7. java.io.InputStream
- Java IO(二) 之 InputStream
- Java IO 之 InputStream源码
- Java IO(二): InputStream
- java io InputStream 转 byte
- 编译错误导致浪费10多分钟, 编译错误的提示:xxx does not name a type xxx
- 加拿大留学热门专业解读之计算机专业
- 本地Eclipse中Tomcat运行测试环境代码
- 剑指offer(11)-包含min函数的栈
- HDU 5909 Tree Cutting (树形dp+FWT)
- java io -- InputStream
- ListView控件相关用法
- 【POJ 3321】【dfs序(讲解)+(树状数组或者线段树)】Apple Tree【给你一颗树,最初每个节点上都有一个苹果,有两种操作单点修改和查询子树的苹果个数】
- 我给程序员新手写简历的一些建议
- git介绍
- 关于远程服务
- 简明 Vim 练级攻略以及基础操作
- 第69篇Chrome扩展USB开发(五)及php
- 读研如何提高技术之我见