1. 程式人生 > >JAVA IO (長期更新)

JAVA IO (長期更新)

1.OutputStream 類

1.1 void write(int b) 方法
本來應該是接受一個無符號的1個位元組的整數(0-255).
接受 Int型資料,但是java內部其實會將b 轉換成0-255之間的數字,原因是Stream是以位元組為讀取單位的. 具體規則如下: b=b& 0x000000FF
然後將結果看做是無符號1位元組整型處理。Java內部用補碼來表示正數和負數。
首先針對正數來說:正數的補碼是他本身。故直接擷取後8位,當做無符號二進位制整數處理即可。
針對負數來說:Java中用補碼來表示負數。所以舉個例子 :-130 :將-130的絕對值表示成4個位元組的有符號型別 0000 0000 0000 0000 0000 0000 1000 0010 ,然後取反碼加一 得:
1111 1111 1111 1111 1111 1111 0111 1110 ,然後擷取後八位,便是126.
write()方法僅僅是傳送一個位模式 ,但是這個位模式如何解釋,例如可以將他對應到ascii碼中,然後打印出來,這個取決於OutputStream的子類處理,舉個例子,如果使用System.out ,那麼就是將這個位模式就解釋成ascii碼,對於無法打印出來的ascii碼,java會輸出亂碼

    public static void main(String[] args) throws Exception{
        System.out.write(-130);
        System.out.flush();
    }
    //輸出結果為~ ,表示的是ascii碼中的126對應的字元

1.2 write(byte[] data) throws IOException
write(byte[] data ,int offset,int length) throws IOException
顯然這裡使用byte表示一個位元組,但是和write(int b) 方法類似,希望接受無符號1位元組整數,所以java內部也會將byte轉換成無符號型別, 具體的公式如下:
int unsignedByte = signedByte >= 0 ? signedByte : 256 + signedByte;
突然發現對於Java來說,雖然只有簡單的集中primitive 資料型別,但是內部還是要進行一系列的轉換。

  1. dataoutputStream和datainputstream
    2.1 write integer
    void writeByte(int b);
    void writeShort(int s);
    void writeInt(int i);
    void writeLong(long l);
    首先需要搞明白從int轉換成byte,和short的原理,
    當int轉換成byte時, 首先令
int byteValue;
int temp = intValue % 256;
if ( intValue < 0) {
byteValue = temp < -128
? 256 + temp : temp; }e lse { byteValue = temp > 127 ? temp - 256 : temp; }

首先先模256,相當於取低8位,但是,注意如果intValue是負數,先取絕對值,然後模256,然後加上負號,因此結果在-255~255之間,判斷餘數是否在-128~127之間,如果不在此區間,然後想個辦法對映到此區間
byteValue = temp < -128 ? 256 + temp : temp;
byteValue = temp > 127 ? temp - 256 : temp;
注意這個和outputSteam中的write(int b) 中處理b的方法不大一樣,如果b不在0~255之間,那麼是取後8位,注意這裡是沒有符號的,原因就是處理的就是無符號單位元組。這裡講int轉換成byte,是轉換成有符號單位元組。
因此

void writeByte(int b);
void writeShort(int s);
void writeInt(int i); 

這三個方法首先將int轉變成byte,short,int,然後使用two’complement ,big-endian 轉變成二進位制。如果寫入到檔案,注意是二進位制檔案,直接用文字編輯器開啟是不會顯示相應的數字的,而是16進位制的表示。

2.2 Strings 和 chars
2.2.1 write

public final void writeChar(int c) throwsIOException
public final void writeChars(String s) throws IOException
public final void writeBytes(String s) throws IOException
public final void writeUTF(String s) throws IOException 

第一個方法,將c轉變成無符號二位元組,進行寫操作.
第二個方法逐個讀取字元,轉換成無符號二位元組,進行寫操作。
第三個方法逐個讀取字元,轉換成無符號單位元組,進行寫操作。
第四個方法逐個讀取位元組,轉換成無符號二位元組,然後轉換使用UTF-8進行編碼,比如漢字,可能編碼成3個位元組
2.2.2 read (這些方法不好)
儘量不要使用datainputStream讀取文字,比如讀取字元,或者字串。