Java IO 之 InputStream源码
来源:互联网 发布:centos arm版 编辑:程序博客网 时间:2024/05/18 05:07
Writer :BYSocket(泥沙砖瓦浆木匠)
微 博:BYSocket
豆 瓣:BYSocket
FaceBook:BYSocket
Twitter :BYSocket
一、InputStream
InputStream是一个抽象类,即表示所有字节输入流实现类的基类。它的作用就是抽象地表示所有从不同数据源产生输入的类,例如常见的FileInputStream、FilterInputStream等。那些数据源呢?比如:
1) 字节数组(不代表String类,但可以转换)
2) String对象
3) 文件
4) 一个其他种类的流组成的序列化 (在分布式系统中常见)
5) 管道(多线程环境中的数据源)
等等
二者,注意它是属于字节流部分,而不是字符流(java.io中Reader\Writer,下面会讲到)。
FilterInputStream是为各种InputStream实现类提供的“装饰器模式”的基类。因此,可以分为原始的字节流和“装饰”过的功能封装字节流。
二、细解InputStream源码的核心
源码如下:
/**
* 所有字节输入流实现类的基类
*/
public
abstract
class
SInputStream {
// 缓存区字节数组最大值
private
static
final
int
MAX_SKIP_BUFFER_SIZE =
2048
;
// 从输入流中读取数据的下一个字节,以int返回
public
abstract
int
read()
throws
IOException;
// 从输入流中读取数据的一定数量字节,并存储在缓存数组b
public
int
read(
byte
b[])
throws
IOException {
return
read(b,
0
, b.length);
}
// 从输入流中读取数据最多len个字节,并存储在缓存数组b
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;
}
// 跳过输入流中数据的n个字节
public
long
skip(
long
n)
throws
IOException {
long
remaining = n;
int
nr;
if
(n <=
0
) {
return
0
;
}
int
size = (
int
)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
byte
[] skipBuffer =
new
byte
[size];
while
(remaining >
0
) {
nr = read(skipBuffer,
0
, (
int
)Math.min(size, remaining));
if
(nr <
0
) {
break
;
}
remaining -= nr;
}
return
n - remaining;
}
// 返回下一个方法调用能不受阻塞地从此读取(或者跳过)的估计字节数
public
int
available()
throws
IOException {
return
0
;
}
// 关闭此输入流,并释放与其关联的所有资源
public
void
close()
throws
IOException {}
// 在此输出流中标记当前位置
public
synchronized
void
mark(
int
readlimit) {}
// 将此流重新定位到最后一次对此输入流调用 mark 方法时的位置。
public
synchronized
void
reset()
throws
IOException {
throw
new
IOException(
"mark/reset not supported"
);
}
// 测试此输入流是否支持 mark 和 reset 方法
public
boolean
markSupported() {
return
false
;
}
}
其中,InputStream下面三个read方法才是核心方法:
public
abstract
int
read()
抽象方法,没有具体实现。因为子类必须实现此方法的一个实现。这就是输入流的关键方法。
二者,可见下面两个read()方法都调用了这个方法子类的实现来完成功能的。
public
int
read(
byte
b[])
该方法是表示从输入流中读取数据的一定数量字节,并存储在缓存字节数组b。其效果等同于调用了下面方法的实现:
read(b,
0
, b.length)
如果b
的长度为 0,则不读取任何字节并返回 0
;否则,尝试读取至少 1 字节。如果因为流位于文件末尾而没有可用的字节,则返回值 -1
;否则,至少读取一个字节并将其存储在 b
中。
思考:这时候,怪不得很多时候, b != –1 或者 b != EOF
public
int
read(
byte
b[],
int
off,
int
len)
在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。
该方法先进行校验,然后校验下个字节是否为空。如果校验通过后,
如下代码:
int
i =
1
;
try
{
for
(; i < len ; i++) {
c = read();
if
(c == -
1
) {
break
;
}
b[off + i] = (
byte
)c;
}
}
catch
(IOException ee) {
}
将读取的第一个字节存储在元素 b[off]
中,下一个存储在 b[off+1]
中,依次类推。读取的字节数最多等于 len
。设 k 为实际读取的字节数;这些字节将存储在 b[off]
到 b[off+
k-1]
的元素中,不影响 b[off+
k]
到 b[off+len-1]
的元素。
因为有上面两个read的实现,所以这里InputStream设计为抽象类。
三、小结
1. InputSream 对应着 OutputStream
2. 看源码是享受人家写代码中流露的How
3. 泥瓦匠学习的代码都在github上(同步osc git),欢迎大家点star,提意见,一起进步。地址:https://github.com/JeffLi1993
- Java IO 之 InputStream源码
- JAVA IO源码学习系列之InputStream
- java io之InputStream
- java IO之InputStream
- JDK 1.7 java.io 源码学习之InputStream和OutputStream
- Java IO(二) 之 InputStream
- JDK中java.io.InputStream源码
- java IO之OutputStream和InputStream
- Java IO系列2 InputStream之ObjectInputStream
- Java-IO之超类InputStream
- Java IO系列2 InputStream之ObjectInputStream
- java io操作之InputStream,OutputStream
- java.io之InputStream与OutputStream
- java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
- java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
- Java IO 系列源码分析——InputStream和OutputStream
- IO之InputStream篇
- IO之InputStream篇
- HDU——5427 A problem of sorting
- Eclipse使用
- iOS开发UI系列之UIButton的基本使用
- java 图片缩放、裁剪。
- 使用百度地图SDK,调试时,地图不显示的问题
- Java IO 之 InputStream源码
- Gradle sync failed: peer not authenticated
- vs2013编译g3dlite时出现 min不是std的成员 mangos
- 欢迎使用CSDN-markdown编辑器
- Java-数组转List-判断一个数是否存在数组/List中
- 机器学习-生成学习算法
- Android基础入门教程——2.5.1 Toast(吐司)的基本使用
- Javascript 学习 -- arguments
- C语言实现变长数组