一、ByteArrayInputStream
字节数组输入流,既然叫输入流,总该有个地方输入数据吧,看看它的构造函数
public ByteArrayInputStream(byte buf[]) {
this.buf = buf;
this.pos = 0;
this.count = buf.length;
}
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[ ]就是我们指定的数据源
//数据源,元素的范围[-128,127]
protected byte buf[];
//将要读取buf里的下位置的字节
protected int pos;
//标记的位置,因为reset()后,当前的pos会等于mark,数据源可以重复读
protected int mark = 0;
//数据源的最后可读位置
protected int count;
接下来分析各个方法
public synchronized int read() {
return (pos < count) ? (buf[pos++] & 0xff) : -1;
}
该方法是读取一个字节,一个字节是8位,可是该方法返回值是一个>=0的int值,但是此时buf[pos] == -1,返回的却是255
[-1] = [10000001]原 = [11111110]反 = [11111111]补
[0xff] = [1111 1111]原 = [1111 1111]反 = [11111111]补
---------------------------------------------------------------------
[0000 0000 0000 0000 0000 0000 1111 1111] = 255
这时只要强转为byte型。[11111111] = -1
再者pos++的含义:先利用pos的值,在把pos自增,比如pos == 4, buf[pos++] == buf[4], 然后pos == 5(下一次将要读取的位置)
//把数据读进b[]字节数组里,起始位置在off,最多读取len个字节
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;
}
//计算数据源还有多少字节可读
int avail = count - pos;
if (len > avail) {
len = avail;
}
if (len <= 0) {
//不读
return 0;
}
//把buf[]数组从pos位置复制len个长度字节到b[]数组,起点在b[]数组的off位置
System.arraycopy(buf, pos, b, off, len);
//下一次读取的位置+len
pos += len;
//返回读取的字节数
return len;
}
//跳过多少字节
public synchronized long skip(long n) {
//检查剩余未读字节数
long k = count - pos;
if (n < k) {
k = n < 0 ? 0 : n;
}
//如果n>=k,就跟n没啥事了
pos += k;
//返回跳过的字节数
return k;
}
//还可以读取多少字节
public synchronized int available() {
return count - pos;
}
//参数没什么意义啊
//打个标记
public void mark(int readAheadLimit) {
mark = pos;
}
public synchronized void reset() {
pos = mark;
}
public void close() throws IOException {
}
public class ByteArrayInputStreamDemo implements IDemo{
@Override
public void test() {
byte[] buf = {1,2,3,4,5,6,7,8,9,0,-1,-2,-3,-4,-5,-6,-7,-8,-9};
ByteArrayInputStream in = new ByteArrayInputStream(buf, 0, buf.length);
int data = -1;
while ((data=in.read())!=-1) {
System.out.println("data = "+data);
}
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Demo {
public static void main(String[] args) {
IDemo demo = new ByteArrayInputStreamDemo();
demo.test();
}
}
data = 1
data = 2
data = 3
data = 4
data = 5
data = 6
data = 7
data = 8
data = 9
data = 0
data = 255
data = 254
data = 253
data = 252
data = 251
data = 250
data = 249
data = 248
data = 247
看到没有,由于是int型,负数都变成正值了
//改成强转成byte
while ((data=in.read())!=-1) {
System.out.println("data = "+(byte)data);
}
data = 1
data = 2
data = 3
data = 4
data = 5
data = 6
data = 7
data = 8
data = 9
data = 0
data = -1
data = -2
data = -3
data = -4
data = -5
data = -6
data = -7
data = -8
data = -9
二、ByteArrayOutputStream
字节数组输出流
先看构造函数
public ByteArrayOutputStream() {
this(32);
}
public ByteArrayOutputStream(int size) {
if (size < 0) {
throw new IllegalArgumentException("Negative initial size: "
+ size);
}
buf = new byte[size];
}
默认一个32字节的内存空间
成员变量
输入的数据都保存在这
protected byte buf[];
表示该还可以利用多少字节,也许buf里满满是数据,但是count == 0,说明即使有数据你也不可以用
protected int count;
//是否要扩容,因为我们不断的想buf[]里写,迟早会满
private void ensureCapacity(int minCapacity) {
if (minCapacity - buf.length > 0)
// 需要的容量>buf.length
grow(minCapacity);
}
private void grow(int minCapacity) {
// 以前的容量
int oldCapacity = buf.length;
//初步计算新的容量是oldCapacity的2倍
int newCapacity = oldCapacity << 1;
if (newCapacity - minCapacity < 0)
//
newCapacity = minCapacity;
if (newCapacity < 0) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
}
// byte[] copy = new byte[newCapacity];
// System.arraycopy(original, 0, copy, 0, Math.min(original.length, newCapacity));
buf = Arrays.copyOf(buf, newCapacity);
}
public synchronized void write(int b) {
ensureCapacity(count + 1);
buf[count] = (byte) b;
count += 1;
}
写入一个字节,注意参数是int型,
public synchronized void write(byte b[], int off, int len) {
if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) - b.length > 0)) {
throw new IndexOutOfBoundsException();
}
ensureCapacity(count + len);
System.arraycopy(b, off, buf, count, len);
count += len;
}
把数组b[ ]里的数据从off位置向buf[]里写入len个字节
public synchronized void writeTo(OutputStream out) throws IOException {
out.write(buf, 0, count);
}
public synchronized void reset() {
count = 0;
}
//获取buf[]字节数组的副本数据
public synchronized byte toByteArray()[] {
return Arrays.copyOf(buf, count);
}
public synchronized int size() {
return count;
}
public synchronized String toString() {
return new String(buf, 0, count);
}
public synchronized String toString(String charsetName)
throws UnsupportedEncodingException
{
return new String(buf, 0, count, charsetName);
}
@Deprecated
public synchronized String toString(int hibyte) {
return new String(buf, hibyte, 0, count);
}
public void close() throws IOException {
}