ByteArrayOutputStream 的 write(byte b[], int off, int len)
源码分析:
protected byte buf[];
public synchronized void write(byte b[], int off, int len) {
// 判断传过来的数据及参数
// 源数组偏移量off 起始位置 是否处在[0,b.length)
// 结束位置 是否处在[0,b.length)
if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) - b.length > 0)) {
throw new IndexOutOfBoundsException();
}
// 再次确定当前的容量是否满足b[] 的添加。
ensureCapacity(count + len);
// 将b[]的起始下标off开始复制给buf[]的起始下标count,复制长度是len
System.arraycopy(b, off, buf, count, len);
// 数组已存在数据长度更新。
count += len;
}
private void ensureCapacity(int minCapacity) {
// overflow-conscious code
// 追加之后的最小长度 比 当前数组长 扩容
if (minCapacity - buf.length > 0)
grow(minCapacity);
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = buf.length;
// 假定扩容的新数组的长度 扩容一倍,变成原来的2倍。
int newCapacity = oldCapacity << 1;
// 假定扩容长度仍不满足最小长度
if (newCapacity - minCapacity < 0)
// 直接使用所需要的最小长度作为 新数组的长度。
newCapacity = minCapacity;
// 新数组的长度 比 Integer.MAX_VALUE - 8 还要大
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 将原数组copy并扩容。
buf = Arrays.copyOf(buf, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
// 容量溢出
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
// 判断所需最小长度 是不是比Integer.MAX_VALUE - 8 还要大
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
结论:
- ByteArrayOutputStream 的 write(…)是数据存到了byte数组;
- 并在每次write的时候判断是否拥有足够的长度去追加复制传过来的数据。
FileOutputStream的 write(byte b[], int off, int len)
源码分析:
public void write(byte b[], int off, int len) throws IOException {
writeBytes(b, off, len, append);
}
/**
* 将子数组写入字节序列
*/
private native void writeBytes(byte b[], int off, int len, boolean append)
throws IOException;
结论:
- FileOutputStream 的 write(…)是数据存到了其他位置,本地并没有保存每次传入的数据;
PS:FileOutputStream 写入的时候可以通过标志位 append确定是追加还是覆盖。