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.本章,我们会 ...
随机推荐
- python unicode 转中文 遇到的问题 爬去网页中遇到编码的问题
How do convert unicode escape sequences to unicode characters in a python string 爬去网页中遇到编码的问题 Python ...
- 利用python 实现微信公众号群发图片与文本消息功能
在微信公众号开发中,使用api都要附加access_token内容.因此,首先需要获取access_token.如下: #获取微信access_token def get_token(): paylo ...
- linux 下source、sh、bash、./执行脚本的区别
原文地址:http://blog.csdn.net/caesarzou/article/details/7310201 source命令用法: source FileName 作用:在当前bash环境 ...
- java_web学习(3)XML基础
XML 技术概述 XML是一种通用的数据交换格式.为实现计算机之间的文档交换而设计的文档内容编写规范,语法与HTML相似;XML的作用:统一信息的结构,实现不同系统之间的相互通信;目前许多系统的配置文 ...
- 一点养老APP模式定制系统平台源码
一点养老APP模式定制系统开发:136.1013.1824电/微:搭建一点养老APP模式定制系统平台.专注于为企业和商家客户提供基于腾讯微信公众平台系统程序和APP等开发服务,中国养老金融50人论坛2 ...
- oc是一个全动态语言,oc的一切都是基于runtime实现的!
oc是一个全动态语言,oc的一切都是基于runtime实现的! 从以下三方面来理解runtime吧! 1. 传统的面向过程的语言开发,例如c语言.实现c语言编译器很简单,只要按照语法规则实现一个LAL ...
- C#多线程-volatile、lock关键字
volatile是C#中最简单的一种同步关键字,其意义是针对程序中一些敏感数据,不允许多线程同时访问,保证数据在任何访问时刻,最多有一个线程访问,以保证数据的完整性,虽与java中的synchroni ...
- swift 使用pod管理
在oc 中使用pod 管理第三方库还是很方便的 今天来在swift中使用pod 来管理第三方库 其实还是很简单的 和oc 区别不大 下面来说说我遇到的一些问题及解决方法 当然使用pod 你要先安装p ...
- ACE首页更改
@{ Layout = null; } <!DOCTYPE html> <html lang="zh-cn"> <head> <meta ...
- Pomelo的Filter
在pomelo中,filter分为before filter和after filter.在一个请求到达Handler被处理之前,可以经过多个before Filter组成的filter链进行一些前置处 ...