Java IO系列1 字节流之ByteArrayInputStream与ByteArrayOutputStream

一、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 {
    }


 
 
 
 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值