java(jdk1.7) IO系列01之InputStream和OutputStream解析
1.InputStream和OutputStream简介
在java中InputStream和OutputStream分别代表字节输入流和字节输出流,表示以字节的方式来实现进程或者程序的通信,InputStream是输入流,表示以字节的方式从文件(FileInputStream)或者字节数组(ByteArrayInputStream)等读取数据,与之相对应的OutputStream是输出流,表示以字节的方式向文件(FileOutputStream)或者字节数组(ByteArrayOutputStream)等写入数据,InputStream和OutputStream分别是所有的字节流的超类,定义了字节输入流和字节输出流的抽象方法和公用实现,这里使用设计模式中的模版模式,超类定义一些公用的实现和相关的方法的约束,子类实现。下面让我们来看一些InputStream和OutputStream的源码
2.InputStream源码解析
package java.io;
public abstract class InputStream implements Closeable { //定义可以跳过的最大字节数
private static final int MAX_SKIP_BUFFER_SIZE = 2048; //抽象读取方法,定义读取一个字节的方法约束,让子类去实现,
public abstract int read() throws IOException; //把读取的字节放到byte数组中,返回的是读取字节的数量
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
//具体的读取字节到字节数组的实现,并提供读取到字节数组b的起始位置off和读入的长度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;
}
//先读取一个字节,如果返回-1,说明当前流中没有数据,直接返回-1
int c = read();
if (c == -1) {
return -1;
}
//如果有数据,则把数据存到b中
b[off] = (byte)c; int i = 1;
try {
//通过循环读取,然后把读取的内容存到传入的buffer中
for (; i < len ; i++) {
c = read();
//如果返回-1,则表示当前读取到文件的结尾
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
} catch (IOException ee) {
}
return i;//返回读取的字节的数量
} //返回真实跳过的字节的数量
public long skip(long n) throws IOException { long remaining = n;
int nr;
//如果当前要求跳过0个,则直接返回0
if (n <= 0) {
return 0;
}
//字符缓冲区的大小不能大于2048.跳过的数量n可能大于2048.
//这里有个原因,为什么不直接声明一个和跳过字节n一样大小的数组。因为内存是个很昂贵的资源,如果一个文件很大的话,一次在内存中声明一个很大的内存,
//一方面会占用很大的内存,另一方面也影响垃圾回收 int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
byte[] skipBuffer = new byte[size];//定义一个缓冲记录跳过的字节的数量
while (remaining > 0) {
//如果跳过的数量大于2048,则通过缓冲区多次执行read方法计算跳过的数量
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 {} //标记一个位置,然后执行reset方法的时候可以重新回到标记的位置
public synchronized void mark(int readlimit) {} //重新从标记的位置读取
public synchronized void reset() throws IOException {
throw new IOException("mark/reset not supported");
} //表明是否支持标记功能
public boolean markSupported() {
return false;
} }
3.OutputSteam源码解析
public abstract class OutputStream implements Closeable, Flushable {
//写入一个字节b到输入流
public abstract void write(int b) throws IOException;
//把字节数组b中的字节写入到输入流中
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
//把字节数组b中的字节写入到输入流中,并提供控制参数,从字节数组的那个位置开始读取,以及读取多长的长度
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]);
}
}
//刷新输出流,强制把字符缓冲中的字节从内存中写入到输出流中,如果输出流是内存比如ByteArrayOutputStream等,则该实现为空
public void flush() throws IOException {
}
//关闭输出流,并释放资源,如果子类不需要,则该实现为空
public void close() throws IOException {
}
}
4.结语
虽然InputStream和OutputStream的两个抽象类的实现比较简单,代码量比较少,但是我们还是可以从中学到一些东西,比如模版设计模式的使用方法,代码中对方法参数的校验逻辑等。多多体会别人写的代码,总会学到一些东西,或许现在看不出来有什么用,但是对你的影响会慢慢看出来的。
===============================================================
努力工作,用心生活
===============================================================
java(jdk1.7) IO系列01之InputStream和OutputStream解析的更多相关文章
- java io系列01之 "目录"
java io 系列目录如下: 01. java io系列01之 "目录" 02. java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括 ...
- Java 之 I/O 系列 01 ——基础
Java 之 I/O 系列 目录 Java 之 I/O 系列 01 ——基础 Java 之 I/O 系列 02 ——序列化(一) Java 之 I/O 系列 02 ——序列化(二) 整理<疯狂j ...
- Java IO(四) InputStream 和 OutputStream
Java IO(四) InputStream 和 OutputStream 一.介绍 InputStream 和 OutputStream 是字节流的超类(父类),都是抽象类,都是通过实例化它们的子类 ...
- Java:IO流之字节流InputStream、OutputStream详解
字节流: (抽象基类)InputStream类(读): (抽象基类)OutputStream类(写): InputStream: 构造方法摘要 InputStream() ...
- JAVA IO包的整理---------InputStream和OutputStream
一:OutPutStream类: public abstract class OutputStream extends Object implements Closeable, Flushable 这 ...
- Java精选笔记_IO流(字节流、InputStream、OutputStream、字节文件、缓冲区输入输出流)
字节流 操作图片数据就要用到字节流. 字符流使用的是字符数组char[],字节流使用的是字节数组byte[]. 字节流读写文件 针对文件的读写,JDK专门提供了两个类,分别是FileInputStre ...
- java 20 - 4 IO流概述和一个简单例子解析
IO流的分类: 流向: 输入流 读取数据 输出流 写出数据 数据类型: 字节流 字节输入流 读取数据 InputStream 字节输出流 写出数据 OutputStream 字符流 字符 ...
- java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
我们以ByteArrayInputStream,拉开对字节类型的“输入流”的学习序幕.本章,我们会先对ByteArrayInputStream进行介绍,然后深入了解一下它的源码,最后通过示例来掌握它的 ...
- java io系列03之 ByteArrayOutputStream的简介,源码分析和示例(包括OutputStream)
前面学习ByteArrayInputStream,了解了“输入流”.接下来,我们学习与ByteArrayInputStream相对应的输出流,即ByteArrayOutputStream.本章,我们会 ...
随机推荐
- 《Web接口开发与自动化测试 -- 基于Python语言》 ---前言
前 言 本书的原型是我整理一份Django学习文档,从事软件测试工作的这六.七年来,一直有整理学习资料的习惯,这种学习理解再输出的方式对我非常受用,博客和文档是我主要的输出形式,这些输出同时也帮 ...
- 【动态规划】Gym - 101102A - Coins
Hasan and Bahosain want to buy a new video game, they want to share the expenses. Hasan has a set of ...
- 基于 Python 和 Scikit-Learn 的机器学习介绍
Reference:http://mp.weixin.qq.com/s?src=3×tamp=1474985436&ver=1&signature=at24GKibw ...
- 【Xilinx-Petalinux学习】-03-PetaLinux通过eMMC方式启动
前面说的我的硬件上有一颗eMMC的芯片,型号是MTFC4GACAJCN-4M IT,有4GB的容量. BOOT.bin的文件较小,只有不到3MB,但是image.ub的文件根据不同的需求,将来可能会越 ...
- java系列--JSON数据的处理
http://blog.csdn.net/qh_java/article/details/38610599 http://www.cnblogs.com/lanxuezaipiao/archive/2 ...
- php模式设计之 策略模式
策略模式: 策略模式设计帮助构建的对象不必自身包含逻辑,而是能够根据需要利用其他对象中的算法. 使用场景: 例如有一个CD类,我们类存储了CD的信息. 原先的时候,我们在CD类中直接调用getCD方法 ...
- 【WebStorm】前端工具开发利器webstrom专篇...更新中
http://my.oschina.net/maomi/blog/137807#OSC_h2_5 WebStorm混搭svn WebStorm混搭nodeJS webstorm简单介绍 webstor ...
- 上传预览 easyui部分控件获取focuse 表单验证
js: $(document).ready(function () { //$('#creater').combobox({ // url: '/VMS.UI/BindData/ScheamData? ...
- 我用Cocos2d-x模拟《Love Live!学院偶像祭》的Live场景(一)
同样从CSDN搬过来 博客开这么久了,就发过一篇很水的文章,一直想写点正式的东西.这次准备开工一个仿其他游戏的简单小游戏,于是开博客把开发过程记录下来.这一系列文章主要讲,我是如何从零开始使用Coco ...
- Java线程:线程安全类和Callable与Future(有返回值的线程)
一.线程安全类 当一个类已经很好的同步以保护它的数据时,这个类就称为线程安全的.当一个集合是安全的,有两个线程在操作同一个集合对象,当第一个线程查询集合非空后,删除集合中所有元素的时候,第二个线程也来 ...