/**
*
* 功能說明:讀取指定路徑文件爲字節數組
* @param classPath
* @return byte[]
* @time:2016年9月20日下午11:42:58
* @author:linghushaoxia
* @exception:
*
*/
public static byte[] readBytes(String filePath){
//返回結果
byte[] result = null;
BufferedInputStream inputStream = null;
ByteOutputStream outputStream=null;
try {
inputStream=new BufferedInputStream(new FileInputStream(filePath));
outputStream= new ByteOutputStream();
int bufferSize=1024;
byte[] buffer=new byte[bufferSize];
while(inputStream.available()>0){
//還未讀取的字節個數
int ava = inputStream.available();
if(ava<bufferSize){
bufferSize=ava;
}
inputStream.read(buffer, 0, bufferSize);
outputStream.write(buffer, 0, bufferSize);
}
//存在問題
result = outputStream.getBytes();
//正確,官方不建議使用
byte[] byteArray=outputStream.toByteArray();
//更好一些的解決辦法,使用ByteArrayOutputStream
} catch (Exception e) {
e.printStackTrace();
}finally{
/**
* 關閉輸入輸出流
*/
if (inputStream!=null) {
try {
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (outputStream!=null) {
outputStream.close();
}
}
return result;
}
使用ByteOutputStream.getBytes()會得到包含空數據的字節流,當然和文件的真實數據就不相符了。
原因在於,ByteOutputStream.getBytes獲取的數據包含擴大容量的初始字節;這裏涉及到兩個關鍵屬性buf和count
buf:ByteOutputStream的字節緩衝區
count:實際字節的個數
ByteOutputStream.getBytes,直接返回buf,而buf包含擴容後得到的默認值字節
ByteOutputStream.toByteArray(),則是新建一個字節數組,只讀取buf的一部分:count個長度,這是正確的。
關鍵代碼如下
ByteOutputStream.getBytes()中涉及到buf的部分:
/**
* Ensure that the buffer has at least this much space.
*/
private void ensureCapacity(int space) {
int newcount = space + count;
if (newcount > buf.length) {
byte[] newbuf = new byte[Math.max(buf.length << 1, newcount)];
System.arraycopy(buf, 0, newbuf, 0, count);
buf = newbuf;
}
}
public void write(byte[] b, int off, int len) {
ensureCapacity(len);
System.arraycopy(b, off, buf, count, len);
count += len;
}
ByteOutputStream.toByteArray()相關部分:
/**
* Evil buffer reallocation method.
* Don't use it unless you absolutely have to.
*
* @deprecated
* because this is evil!
*/
public byte toByteArray()[] {
byte[] newbuf = new byte[count];
System.arraycopy(buf, 0, newbuf, 0, count);
return newbuf;
}
造成這個問題的原因,在於數據的不一致性:count所代表的真實數據的長度和分配空間得到的buf數組的長度,不一樣。
可見,分配空間中存在一個必須要注意的問題,那就是維護實際數據長度和實際分配空間的關係。
測試環境:Oracle JDK1.7。