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解析的更多相关文章

  1. java io系列01之 "目录"

    java io 系列目录如下: 01. java io系列01之  "目录" 02. java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括 ...

  2. Java 之 I/O 系列 01 ——基础

    Java 之 I/O 系列 目录 Java 之 I/O 系列 01 ——基础 Java 之 I/O 系列 02 ——序列化(一) Java 之 I/O 系列 02 ——序列化(二) 整理<疯狂j ...

  3. Java IO(四) InputStream 和 OutputStream

    Java IO(四) InputStream 和 OutputStream 一.介绍 InputStream 和 OutputStream 是字节流的超类(父类),都是抽象类,都是通过实例化它们的子类 ...

  4. Java:IO流之字节流InputStream、OutputStream详解

    字节流: (抽象基类)InputStream类(读): (抽象基类)OutputStream类(写):   InputStream: 构造方法摘要 InputStream()              ...

  5. JAVA IO包的整理---------InputStream和OutputStream

    一:OutPutStream类: public abstract class OutputStream extends Object implements Closeable, Flushable 这 ...

  6. Java精选笔记_IO流(字节流、InputStream、OutputStream、字节文件、缓冲区输入输出流)

    字节流 操作图片数据就要用到字节流. 字符流使用的是字符数组char[],字节流使用的是字节数组byte[]. 字节流读写文件 针对文件的读写,JDK专门提供了两个类,分别是FileInputStre ...

  7. java 20 - 4 IO流概述和一个简单例子解析

    IO流的分类:  流向: 输入流 读取数据  输出流 写出数据 数据类型:  字节流  字节输入流 读取数据 InputStream  字节输出流 写出数据 OutputStream  字符流  字符 ...

  8. java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)

    我们以ByteArrayInputStream,拉开对字节类型的“输入流”的学习序幕.本章,我们会先对ByteArrayInputStream进行介绍,然后深入了解一下它的源码,最后通过示例来掌握它的 ...

  9. java io系列03之 ByteArrayOutputStream的简介,源码分析和示例(包括OutputStream)

    前面学习ByteArrayInputStream,了解了“输入流”.接下来,我们学习与ByteArrayInputStream相对应的输出流,即ByteArrayOutputStream.本章,我们会 ...

随机推荐

  1. 大数据竞赛平台——Kaggle 入门

    Reference: http://blog.csdn.net/witnessai1/article/details/52612012 Kaggle是一个数据分析的竞赛平台,网址:https://ww ...

  2. Twisted源码分析系列01-reactor

    转载自:http://www.jianshu.com/p/26ae331b09b0 简介 Twisted是用Python实现的事件驱动的网络框架. 如果想看教程的话,我觉得写得最好的就是Twisted ...

  3. STM8S003/005/007芯片解密单片机解密程序提取复制经验分享!

    STM8S003/005/007芯片解密单片机解密程序提取复制 芯片解密型号: STM8S003K3T6,STM8S005K6T6,STM8S007C8T6,STM8S003F3P6 STM8S005 ...

  4. java 之 Spring 框架(Java之负基础实战)

    1.Spring是什么 相当于安卓的MVC框架,是一个开源框架.一般用于轻型或中型应用. 它的核心是控制反转(IoC)和面向切面(AOP). 主要优势是分层架构,允许选择使用哪一个组件.使用基本的Ja ...

  5. Java网络编程总结

    网络编程: 端口: 物理端口: 逻辑端口:用于标识进程的逻辑地址,不同进程的标识:有效端口:0~65535,其中0~1024系统使用或保留端口. java 中ip对象:InetAddress. imp ...

  6. HTML5 + AJAX ( 原生JavaScript ) 异步多文件上传

    这是在上篇 HTML5 + AJAX ( jQuery版本 ) 文件上传带进度条 的修改版本.后台代码不变就可以接着使用,但是脚本不再使用jQuery了,改为原生的 JavaScript 代码,所以我 ...

  7. 数据契约(DataContract)的作用

    服务契约定义了远程访问对象和可供调用的方法,数据契约则是服务端和客户端之间要传送的自定义数据类型. 一旦声明一个类型为DataContract,那么该类型就可以被序列化在服务端和客户端之间传送,如下所 ...

  8. 开发团队在TFS中使用Git Repository (二)

    使用Git作分支时,仅仅是对提交历史记录的一个引用,创建分支成本非常低,分支的切换快且简单.在分支管理方面,相对其他的版本管理工具,Git可谓是一骑绝尘. 开发过程中,我们可以针对任何的大小功能进行分 ...

  9. 【G】开源的分布式部署解决方案(二) - 好项目是从烂项目基础上重构出来的

    分析目前项目结构 眼前出现这么一坨坨的文件夹,相信很多人已经看不下去了.是的,首先就是要把它给做掉. 按照这个项目文件夹的命名意图,大概可以划分如下: 1.Business:业务代码 2.Data:数 ...

  10. Bezier(贝塞尔)曲线简介

    在计算机图形学中,Bezier曲线被广泛用于对平滑的曲线进行建模,对其有适当的了解是必要的.一条Bezier曲线由一系列控制点定义,称为曲线的阶数,由此可知,使用两个控制点()可以定义一条一阶Bezi ...