java的数据源有很多,比如:文件、网络、管道、命令行,甚至是内存。
其实我个人认为 java对流的源头概念做了更抽象的扩展,让一些本来很直观的操作,也封装为io流的形式,会增加理解的坡度。
比如: java.io.ByteArrayInputStream 其实完全可以不设计为流的一部分,因为其本质不过是对byte[] 的一个数据读取的处理,即使不用流的概念,完全可以自己实现自己想要的功能。
但是在某些情况下,使用这种流可能和其他的流更好统一交互。所以从这一点看还是有点意义的
下面就分析java.io.ByteArrayInputStream 的源码实现,因为完全是对byte[]的处理,所以很简单。
另外:
数组是java数据结构中常用的底层数据结构。字节流的操作很大程度上是byte[]字节数组的操作 或复制 或移动 或扩展。
package java.io;
/**
其内部是通过保持一个byte[] 来实现的
*/
public
class ByteArrayInputStream extends InputStream {
protected byte buf[];
/**
* --标志从inputStream读取的下一个字符的索引
* --pos 不能为负值
*--pos 必须不大于 count
* --read方法读取的下一个byte是 buf[pos]
*/
protected int pos;
/**
*-- 当前在stream中 标记的位置
*--初始化时 ByteArrayInputStream 被标记为0
*-- mark(int)方法可以设定mark的值
*/
protected int mark = 0;
protected int count;
/**
* 构造方法需要传递 byte[]数组
*/
public ByteArrayInputStream(byte buf[]) {
this.buf = buf;
this.pos = 0; //当前位置设置为0
this.count = buf.length; //count 设置为buf.length
}
/**
*同上,只是buf 的数组事从offset开始算的
*/
public ByteArrayInputStream(byte buf[], int offset, int length) {
this.buf = buf;
this.pos = offset;
this.count = Math.min(offset + length, buf.length);
this.mark = offset;
}
/**
* 读下一个字节。可以看到此字节就是buf[pos++]
*/
public synchronized int read() {
return (pos < count) ? (buf[pos++] & 0xff) : -1;
}
/**
* 其覆盖了父类的方法,父类是循环调用read方法
其实read方法就是 buf数组内容 copy 到 b中。
*/
public synchronized int read(byte b[], int off, int len) {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
}
if (pos >= count) {
return -1;
}
if (pos + len > count) {
len = count - pos;
}
if (len <= 0) {
return 0;
}
System.arraycopy(buf, pos, b, off, len); //其实就是数组的复制操作,java对很多底层的操作归根结底,大部分都是对数组的操作。
pos += len;
return len;
}
/**
* 跳过n字节,其实就是对pos的处理,标志当前应该读的下一个字符
*/
public synchronized long skip(long n) {
if (pos + n > count) {
n = count - pos;
}
if (n < 0) {
return 0;
}
pos += n;
return n;
}
/**
*还剩下多少可以读的自己
*/
public synchronized int available() {
return count - pos;
}
public boolean markSupported() {
return true;
}
/**
* 可设置标记
*/
public void mark(int readAheadLimit) {
mark = pos;
}
/**
*重置后讲从最初的位置开始读
*/
public synchronized void reset() {
pos = mark;
}
/**
*ByteArrayInputStream 的close 方法无效
*/
public void close() throws IOException {
}
}
分享到:
相关推荐
a)java.sql b) java.util c) java.math d) java.io 2.不属于java.io包中的接口的一项是(C) a)DataInput b) DataOutput c) DataInputStream d) ObjectInput 3. ByteArrayOutputStream将下列哪一项作为输出流 C a)...
【IT十八掌徐培成】Java基础第16天-04.ByteArrayInputStream-ByteArrayOutputStream.zip
本文所述实例为一个天气预报中的android代码,...import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import ja
import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.ByteArrayInputStream; import java.util.List;
前言 Android端可以对字符串...import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutput
示例代码:import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import com.fasterxml.jackson.databind.ObjectMapper; import de.undercouch.bson4jackson.BsonFactory; public ...
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; ...
import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.Reader;import java.sql.Clob;import java.sql.Connection;import java....
在Java的IO中,所有的stream(包括Input和Out stream)都包括两种类型: 1.1 以字节为导向的stream 以字节为导向的stream,表示以字节为单位从stream中读取或往stream中写入信息。以字节为导向的stream包括下面几种...
Java IO流学习总结 Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据...
1) ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用 2) StringBufferInputStream:把一个String对象作为InputStream 3) FileInputStream:把一个文件作为InputStream,实现对文件的读取操作 4) ...
IO从大的方向上分为字节流和字符流,包括四个抽象类: 1、输入:Reader, InputStream类型的子类(字符,字节) 2、输出:Writer, OutputStream类型的子类(字符,字节) 决定使用哪个类以及它的构造进程的一般...
|--ObjectOutputStream/:将java对象的基本数据类型和图形写入到OutputStream。 | |--PipedOutputStream/:可以将管道输出流连接到管道输入流来创建通信管道。 | 用方法connect(PipedInputStream snk) 将此管道...
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import android.graphics.Bitmap; import android.graphics.BitmapFactory; public class ImaZipUtil { /** * 压缩图片到指定宽高,...
java语言操作解压缩文件。 /** * 数据压缩 * * @param data * @return * @throws Exception */ public static byte[] compress(byte[] data) throws Exception { ByteArrayInputStream bais = new ...
彻底明白Java的IO系统 一. Input和Output 1. stream代表的是任何有能力产出数据的数据源,或是任何有能力接收数据的接收源。在Java的IO中,所有的stream(包括Input和Out stream)都包括两种类型: 1.1 以字节为...
A) java.io.Exception B) java.lang.Throwable C) java.lang.Exception D) java.lang.Error 题目29:d 程序如下: public class Foo { public static void main(String[] args) { try { ...
Java IO学习 FileInputStream,FileOutputstream 随机存取文件 ByteArrayOutputStream,ByteArrayInputStream
JAVA使用ByteArrayOutputStream、ByteArrayInputStream将对象序列化反序列化,通过JAVA socket实现对象在网络中传输
ByteArrayInputStream 是字节数组输入流。它继承于InputStream。 它包含一个内部缓冲区,该缓冲区包含从流中读取的字节;通俗点说,它的内部缓冲区就是一个字节数组,而ByteArrayInputStream本质就是通过字节数组来...