串流(Stream)的讀取與寫入
Posted by Bruce Tsai
- 在程式開發中串流的應用是必需要學會的一環,而最常遇到的應用情況不外乎檔案或資源的讀寫。
位元資料的讀取
public byte[] readBytes(InputStream in) throws IOException {
if (in == null) throw new IllegalArgumentException();
// 讀取的資料
ByteArrayOutputStream out = new ByteArrayOutputStream();
// 暫存讀取資料
byte[] buffer = new byte[128];
// 讀取位元數
int len;
// 開始讀取
// 以 read() 將串流資料讀入 buffer,回傳值 len 則為讀取的位元數
// 當讀取的位元數為 0 時,表示串流讀取完成
while ((len = in.read(buffer, 0, buffer.length)) > 0) {
// 寫入另一個串流
out.write(buffer, 0, len);
}
// 讀寫完成,關閉串流
out.close();
in.close();
return out.toByteArray();
}
文字資料的讀取
public String readString(InputStream in, String encoding) throws IOException {
if (in == null || encoding == null) throw new IllegalArgumentException();
// 讀取的資料
StringBuilder out = new StringBuilder();
// 暫存讀取資料
char[] buffer = new char[24];
// 讀取位元數
int len;
// 轉換為 reader,並以指定的文字編碼進行讀取
InputStreamReader reader = new InputStreamReader(in, encoding);
// 開始讀取
// 以 read() 將串流資料讀入 buffer,回傳值 len 則為讀取的字元數
// 當讀取的字元數為 0 時,表示串流讀取完成
while ((len = reader.read(buffer, 0, buffer.length)) > 0) {
// 以 StringBuilder 儲存讀入的文字
if (len == buffer.length) {
out.append(buffer);
} else {
out.append(Arrays.copyOfRange(buffer, 0, len));
}
}
// 讀寫完成,關閉串流
reader.close();
in.close();
return out.toString();
}
串流的套嵌
- InputStream 或 OutputStream 在串流中是屬於最頂層的界面,實務上在處理串流的時候會依需要在串流讀取或寫入時,附加一些額外的處理如壓縮、加密、緩衝區等,以多層 stream 的套嵌來完成這些操作。
InputStream is = getInputStream();
// 解密
CipherInputStream cis = new CipherInputStream(is, cipher);
// 解壓縮
GZIPInputStream gis = new GZIPInputStream(cis);
// 緩衝讀取
BufferedInputStream bis = new BufferedInputStream(gis);
while ((len = bis.read(buffer, 0, buffer.length)) > 0) {
// code here
}
// 需依順序關閉
bis.close();
gis.close();
cis.close();
is.close();