Java的I/O框架之ByteArrayInputStream和ByteArrayOutputStream

ByteArrayInputStream和ByteArrayOutputStream用於處理字節流的輸入輸出,底層都是數組。

ByteArrayInputStream

構造方法
ByteArrayInputStream(byte buf[])    使用數組buf[]構造新的數組流
ByteArrayInputStream(byte buf[], int offset, int length)
使用數組從下表offset開始,最多length長度的子數組來構造新的數組流

synchronized int read() 
synchronized int read(byte b[], int off, int len)
synchronized long skip(long n)
synchronized int available()
boolean markSupported()
void mark(int readAheadLimit)
synchronized void reset()
void close()

源碼解析:
ByteArrayInputStream方法都用synchronized關鍵字標識,因此是線程安全的。

ByteArrayInputStream具有成員變量protected byte buf[]用於存儲數據,protected int pos標識了下一個讀取的元素在數組中的下標,protected int mark用於標記索引,protected int count記錄字節流的長度。

int read() 返回下一個讀取的字節(可以用(Char)強轉爲字節)
int read(byte b[], int off, int len) 將字節流當前位置開始的len個字節寫入數組,從數組的索引off位置開始寫入
long skip(long n) 跳過接下來的n個字節,即將當前索引pos設置爲pos+n,或者當n大於count-pos時,跳過接下來的count-pos個字節
int available() 返回字節流中剩餘字節的數量
boolean markSupported() 當前字節流是否支持mark/reset功能
void mark(int readAheadLimit) 將mark設置爲pos,readAheadLimit字段沒有意義
void reset() 將pos重置爲mark
void close() 關閉字節流

public class ByteArrayExample {

   // 自定義常數5
public static final int LEN=5;
// 對應英文字母“abcddefghijklmnopqrsttuvwxyz”
private static final byte[] ArrayLetters = {
        0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
        0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
};

public static void main(String[] args) throws IOException {
    String tmp = new String(ArrayLetters);
    System.out.println("ArrayLetters="+tmp);

    tesByteArrayInputStream() ;
}

/**
 * 測試ByteArrayInputStream
 */
public static void tesByteArrayInputStream() throws IOException {
    ByteArrayInputStream bais=new ByteArrayInputStream(ArrayLetters);

    //讀取下個字節
    int data=bais.read();
    System.out.println("當前字節爲:"+ (char)data);

    //寫入數據到數組b,寫入起始位置爲off,長度爲len,從字節流下一字節開始寫入
    byte b[]=new byte[LEN];
    bais.read(b,0,LEN);
    String tempb=new String(b);
    System.out.println("寫入後的數組是"+tempb);

    //寫入數組後,中間的元素已經被跳過了
    data=bais.read();
    System.out.println("當前字節爲:"+ (char)data);

    //跳過兩個字節
    long skipNum=bais.skip(2);
    data=bais.read();
    System.out.println("跳過的字節數是: "+skipNum+",當前字節是: "+ (char)data);
    //字節流可用字節數
    System.out.println("字節流可用字節數爲: "+bais.available());
    //當前字節流是否支持mark/reset功能
    System.out.println("當前字節流是否支持mark/reset功能: "+bais.markSupported());
    //將當前pos作爲mark
    bais.mark(0);
    data=bais.read();
    System.out.println("標記位置的字節是: "+ (char)data);
   //跳過LEN個字節,再reset到上次mark的位置
    bais.skip(LEN);
    bais.reset();
    data=bais.read();
    System.out.println("重置後的字節是: "+ (char)data);

    bais.close();
}
}

ByteArrayOutputStream

構造方法
ByteArrayOutputStream() 構造一個容量爲32的輸出流,容量不夠時數組字節流支持自動擴容
ByteArrayOutputStream(int size) 構造一個容量爲size的輸出流


void write(int b)
void write(byte b[], int off, int len)
void write(byte b[])
void flush()
void writeTo(OutputStream out)
void reset()
byte toByteArray()[]
int size()
String toString()
String toString(String charsetName)
close()

源碼解析:

ByteArrayOutputStream方法都用synchronized關鍵字標識,因此是線程安全的。

ByteArrayOutputStream具有緩衝數組 protected byte buf[]用於存儲數據,protected int count記錄的是存儲素組buf的數據量。

void ensureCapacity(int minCapacity) 保證存儲數組的容量大於minCapacity,如果不滿足的話,調用grow()方法擴大底層數組容量。

void write(int b) 將int類型的b轉換成byte,寫入字節流

void write(byte b[], int off, int len) j將數組中長度爲len的數組寫入到字節流數組中,寫入的起始位置爲off

void writeTo(OutputStream out) 將字節輸出流的所有數據寫入到字節輸出流out

void reset() 重置當前字節數組輸出流,將count置爲0,使當前字節數組輸出流可以被複用

byte toByteArray()[] 將當前字節數組輸出流數據存入一個新的byte數組

int size() 返回當前字節數組的數據量

String toString(String charsetName) 將當前字節數組裝換成對應charsetName編碼標準的字符串

void flush() 流操作中,數據都是先寫到緩衝區,然後再寫入文件,flush()方法在close()方法之前調用,可以強制緩衝區的數據寫入文件,防止close()方法關閉流後,緩衝區還沒有寫入文件的數據丟失

public class ByteArrayExample {

   // 自定義常數5
public static final int LEN=5;
// 對應英文字母“abcddefghijklmnopqrsttuvwxyz”
private static final byte[] ArrayLetters = {
        0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
        0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
};

public static void main(String[] args) throws IOException {
    String tmp = new String(ArrayLetters);
    System.out.println("ArrayLetters="+tmp);

    testByteArrayOutputStream();
}

/**
 * 測試ByteArrayOutPutStream
 */
public static void testByteArrayOutputStream() throws IOException {

    ByteArrayOutputStream baos=new ByteArrayOutputStream();

    //向字節數組輸出流寫入字節數組
    baos.write(ArrayLetters,0,LEN);
    System.out.println("寫入ArrayLetters數組的五個元素後後,字節數組輸入流爲:"+baos.toString("utf-8"));
    //向字節數組寫入f對應的int
    baos.write(0x66);
    System.out.println("寫入f後,字節數組輸入流爲:"+baos.toString("utf-8"));
    //獲得字節數組的長度
    System.out.println("字節數組的長度是: "+baos.size());
    //將字節流數組轉換成數組
    byte[] b=baos.toByteArray();
    System.out.println("字節流轉換成的數組: "+new String(b));

    // 將baos寫入到另一個輸出流中
    try {
        ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
        baos.writeTo((OutputStream)baos2);
        System.out.printf("baos2=%s\n", baos2);
    } catch (IOException e) {
        e.printStackTrace();
    }

    baos.flush();
    baos.close();
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章