標籤:java 資料 二進位 io
緩衝區思想:
FileInputStream的read方法是直接從系統中的磁碟中讀取資料,較消耗資源。
緩衝區的作用就是通過封裝類封裝FileInputStream對象fis,通過fis的read方法儲存到緩衝區的位元組數組中,再調用緩衝區的加強read方法,迴圈遍曆位元組數組即可。
解釋:迴圈遍曆位元組數組比遍曆磁碟中的資料要快得多。
源碼:
import java.io.IOException;import java.io.InputStream;public class MyBufferedInputStream {private InputStream input=null;byte[] buf=new byte[1024*4];int count=0,index=0;MyBufferedInputStream2(InputStream input){this.input=input;}public int myRead() throws IOException{if(count==0){count=input.read(buf);if(count<0){return -1;}index=0;}if(count>0){byte b=buf[index];count--;index++;return b*0xff;}return -1;}}
遇到的問題:1、
關於為什麼返回的是:
return b*0xff;
因為資料是由0101二進位的排列組合組成的。
所以有可能出現1111-1111八個1的情況,然而讀一個位元組,相當於讀了一個八個2進位位。
但由於1111-1111的十進位是-1。
<span style="font-size:14px;">解釋:它的最高位是1,所以是負數.按補碼規則,如下等式成立:負數 = 負數的絕對值按位取反+1負數按位取反+1 =負數的絕對值所以11111111按位取反+1 就等於 1.因此,對應-1。</span>
這也就解釋了為什麼用的是byte數組卻要返回int而不是byte的原因。
因為返回int的話,byte會自動提升,而不加&0xff的話,返回的int仍舊是-1。
解釋為何要加&0xff:
為了避免byte的1111-1111轉int變為1111-1111 1111-1111 1111-1111 1111-1111 結果還是-1。
就“與”一下。
1111-1111 1111-1111 1111-1111 1111-1111
& 0000-0000 0000-0000 0000-0000 1111-1111 -->255-->0xff
就能得到正確的值了。
2、
將byte進行int提升,會導致1個位元組變為4個位元組。
往外寫的話按照int往外寫,那應該是原來資料的4倍才對。
但事實為什麼沒有呢?
read方法在向上提升,它在往前面補0,保證不是-1這種情況的發生,而write方法,它其實在做一個強轉動作。
write方法其實就是將最低8位寫進去。剩下的全砍掉。
int在做提升,write在做強轉,所以就能保證來源資料的不變化。
Java自訂位元組流的緩衝區