您的位置:首页 > 编程语言 > Java开发

Java_io体系之InputStream、OutputStream简介、走进源码——03

2013-11-24 12:55 776 查看

Java_io体系之InputStream、OutputStream简介、走进源码——03


一:InputStream


1、       InputStream类简介:

InputStream:字节输入流、是所有字节输入流的父类、本身个抽象类、为字节输入流提供一个标准、和基本的方法及简单的实现、子类可以根据自己的特点进行重写和扩

展。InputStream中有一个抽象方法read()、是字节输入流的核心、要求子类必须实现此方法、此方法也是字节输入流的核心方法、


2、       InputStream 方法简介:


A:构造方法

本身是抽象类、无构造方法。

B:一般方法

int avaliable();查看当前流中可供读取的字节数。

void close();关闭当前流、释放所有与当前流有关的资源。

synchronized void mark(int readlimit);标记当前流的读取的位子。

boolean markSupport();查看当前流是否支持mark。

abstract int read();读取当前流中的下一个字节、并以整数形式返回、若读取到文件结尾则返回-1。

int read(byte[] b);将当前流中的字节读取到字节数组b中、返回实际读取的字节数

int read(byte[] b, int off, int len);将当前流中的len个字节读取到从下标off开始存放的字节数组b中。

synchronized reset();重置当前流的读取位置到最后一次调用mark方法标记的位置。

long skip(long n);跳过(抛弃)当前流中n个字节。返回实际抛弃的字节数。


3、       InputStream源码分析:

/**
* 所有字节输出流的父抽象类。提供字节输入流所共有的基本的读取方法。
*/
public abstract class InputStream implements Closeable {

// skipBuffer的大小
private static final int SKIP_BUFFER_SIZE = 2048;
// 内置字节缓存数组、用于构建skip方法中临时存放抛弃的字节。
private static byte[] skipBuffer;

/**
* 抽象的方法 用于读取输入流中的下一个字节、由其实现类去重写。这也是流的关键方法、下面几个方法都是直接或者间接调用read()方法来实现。
* @return 0 到 255 之间的整数。如果读到流的结尾则返回 -1 。
*/
public abstract int read() throws IOException;

/**
*从方法实现也可看出、他是不断调用read(byte[] b, 0, b.length)这个方法作为其方法体。
* @param      作为一个缓存字节数组来存放从流中读取的字节。
* @return     读取的字节总个数、如果读到结尾、则返回-1.
*/
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}

/**
*不断的调用read()方法来读取流中的字节、存放到  b 中。
* @param  b 用来存放读取的字节的字节缓存数组、off 从b[off]开始放 、len 放len个
* @return 返回读取的字节的总个数。
*/
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;
}

/**
* 返回跳过的字节数的个数。
* 这里根本就看不出这个方法到底有什么实际的用途、但是当看到后面的子类实现类的方法体就知道了。
* @param      n   我们想从从输入流中跳过的字节数
* @return    实际跳过的字节数、因为有可能输入流中没有那么多有效字节被抛弃、此时则会跳过剩余所有字节、返回的字节数也就是跳之前剩余的字节数。
*/
public long skip(long n) throws IOException {
//方法思想:实际抛弃的字节数  = 想要抛弃的字节数  - 剩余需要抛弃的字节数

//记录还剩余多少字节要跳过。
long remaining = n;

//中间变量、记录每次读取的实际字节数
int nr;
//初始化默认大小的全局字节数组。
if (skipBuffer == null)
skipBuffer = new byte[SKIP_BUFFER_SIZE];
//创建临时的用于存放被读取的字节的字节数组、像垃圾桶、回收被跳过的字节、满了之后在读取就清空从新回收。
byte[] localSkipBuffer = skipBuffer;

if (n <= 0) {
return 0;
}
//次循环意义在于记录剩余需要抛弃的字节数
//大条件、如果还有字节需要被跳过、也就是抛弃、没有则结束循环
while (remaining > 0) {
//记录此次实际读取的字节数、后面参数的意义在于防止出现IndexOutOfBoundsException异常。

nr = read(localSkipBuffer, 0,
(int) Math.min(SKIP_BUFFER_SIZE, remaining));
//如果读到输入流结尾、则结束循环。
if (nr < 0) {
break;
}
//修改记录还要抛弃的字节数的值
remaining -= nr;
}
//将n减去还剩多少需要被抛弃的值就是实际抛弃的值
return n - remaining;
}

/**
* 返回输入流中可读取的有效的字节数、若子类提供此功能、则需要重新实现。
*/
public int available() throws IOException {
return 0;
}

/**
* 关闭流、释放所有与此流有关的资源。
*/
public void close() throws IOException {}

/**
* 在输入流中标记当前位置、与reset()结合使用、
* 若子类不提供此功能则调用此方法没有任何效果。
* 若子类提供此功能、则需重新实现。
*/
public synchronized void mark(int readlimit) {}

/**
* 与mark(int readlimit)结合使用、将此流定位到最后一次mark的位置、即调用reset之后、程序继续重mark的位置读取字节流。
* 若子类不支持此方法、调用则会抛出异常、可事先调用下面的markSupported()来查看当前流是否支持此功能。
*/
public synchronized void reset() throws IOException {
throw new IOException("mark/reset not supported");
}

/**
* 查看当前流是否支持mark、默认是false、即如果实现类不重写此方法就意味着其不支持mark。
*/
public boolean markSupported() {
return false;
}
}

二:OutputStream

1、OutputStream简介:

       OutputStream:字节输出流、同InputStream意义相同、本身是一个抽象类、为所有字节输出流提供一个标准、和一些简单的方法及简单实现。其核心方法是一个抽象方法: write(byte b)要求子类必须实现此方法、不同功能的类对此方法的实现方式不
一样、一般情况下子类要重写其大多数方法、或者新增一些方法、用于满足更多的需要。

2、OutputStream 方法简介:

A:构造方法

本身是抽象类、无构造方法。

B:一般方法

abstract void write(byte b);将一个字节写入到当前输出流管道中。

void write(byte[] b);将字节数组b中所有字节写入到当前输出流管道中。

void write(byte[] b, int off, int len);将字节数组b从下标off开始、len个字节写入当前输出流管道中

void flush();flush当前流、将当前流中的所有数据冲刷到目的地中。

void close();关闭当前流、释放与当前流有关的所有资源。



3、OutputStream源码分析:

public abstract class OutputStream implements Closeable, Flushable {
/**
*将一个8位的字节写入到当前字节输出流中。其子类必须重写、实现此方法。
*/
public abstract void write(int b) throws IOException;

/**
* 将字节数组中b.length个字节写入到当前输出流中。此方法相当与write(byte[] b, 0, b.length);因为其内部就是调用下面的方法。
*/
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}

/**
* 将一个字节数组中从下标off开始、len个字节写入到当前输出流中。不断调用write来实现的。
*/
public void write(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) > b.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
for (int i = 0 ; i < len ; i++) {
write(b[off + i]);
}
}

/**
* 将当前输出流中的所有残留数据刷新到目的地中去。
*/
public void flush() throws IOException {}

/**
* 关闭当前输出流、释放所有与此流有关的资源。
*/
public void close() throws IOException {}
}


更多IO内容:java_io 体系之目录

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐