1. 程式人生 > >java IO InputStreamReader

java IO InputStreamReader

InputStream in = new FileInputStream("C:\\file\\hello.txt");
Reader reader = new InputStreamReader(in);

Reader:一個用於讀取字元流的靜態類

//繼承了Reader 
//是位元組流與字元流之間的橋樑
//它讀取位元組流並通過java.nio.charset.Charset charset將其解碼成字元
//我們可以指定charset,也可以使用預設的charset
public class InputStreamReader extends Reader 
private final StreamDecoder sd;  //位元組與字元的轉換器

關於建構函式

//如果構造的時候沒有指定charset,使用預設的charset 
public InputStreamReader(InputStream in) {
        super(in);
        try {
            sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object 
        } catch (UnsupportedEncodingException e) {
            // The default encoding should always be available
            throw new Error(e);
        }
    }

//建立一個使用指定charset的InputStreamReader
 public InputStreamReader(InputStream in, String charsetName)
        throws UnsupportedEncodingException
    {
        super(in);
        if (charsetName == null)
            throw new NullPointerException("charsetName");
        sd = StreamDecoder.forInputStreamReader(in, this, charsetName);
    }

//建立一個使用給定charset的InputStreamReader。
public InputStreamReader(InputStream in, Charset cs) {
        super(in);
        if (cs == null)
            throw new NullPointerException("charset");
        sd = StreamDecoder.forInputStreamReader(in, this, cs);
    }

//建立一個使用給定charset解碼器的InputStreamReader。
 public InputStreamReader(InputStream in, CharsetDecoder dec) {
        super(in);
        if (dec == null)
            throw new NullPointerException("charset decoder");
        sd = StreamDecoder.forInputStreamReader(in, this, dec);
    }
//讀取一個字元,
//返回讀取的字元,如果讀到結尾,則返回-1
//每次都會從底層輸入流中讀取一個或多個位元組
public int read() throws IOException {
        return sd.read();
    }

// 讀取多個字元到一個指定的陣列中
// cbuf 指定的陣列,offset開始儲存字元的位置,length,讀取多少字元
public int read(char cbuf[], int offset, int length) throws IOException {
        return sd.read(cbuf, offset, length);
    }

下面說一下OutputStreamWriter

//OutputStreamWriter 是字元流到位元組流動的橋樑
// 使用了java.nio.charset.Charset charset  //將寫入其中的字元轉換成位元組
//charset  可以通過名稱指定,也可以明確指定,也可以使用平臺指定的
public class OutputStreamWriter extends Writer

建構函式就不寫了 

private final StreamEncoder se; 

//使用write()的時候,會呼叫字元到位元組的轉換器,但注意一下
//傳給write()的字元不會放入緩衝區中,但,字元轉換的位元組會放入緩衝區中而不會直接寫入輸出流
public void write(int c) throws IOException {
        se.write(c);
    }
//自己寫了一個例子
@Test
	public void readerTest() throws IOException{
		InputStream in = new FileInputStream("hello2.txt");
		Reader reader = new InputStreamReader(in);
		OutputStream out = new FileOutputStream("hello3.txt",true);
		Writer writer = new OutputStreamWriter(out);
		char[] cbuf = new char[4];
		while((reader.read(cbuf))!=-1){ //把讀取的位元組轉換成字元放入cbuf 中
			writer.write(cbuf, 0, 3); 從cbuf 0開始中讀取3個字元轉換成位元組放入緩衝區中
		}
		writer.flush(); //重新整理緩衝區
		writer.close();
		reader.close();
	}

關於flush

看了一下 Writer 

//重新整理緩衝區,將緩衝區的位元組全部寫入位元組輸出流,並清空緩衝區
abstract public void flush() throws IOException;

//關閉流,並重新整理它
abstract public void close() throws IOException;

所以,是不是使用了close就可以不用flush了?根據下面的測試,發現是正確的
//測試了一下,這次沒有關閉流和重新整理緩衝區,發現hello3裡沒有寫入
@Test
	public void readerTest() throws IOException{
		InputStream in = new FileInputStream("hello2.txt");
		Reader reader = new InputStreamReader(in);
		OutputStream out = new FileOutputStream("hello3.txt");
		Writer writer = new OutputStreamWriter(out);
		char[] cbuf = new char[4];
		while((reader.read(cbuf))!=-1){
			writer.write(cbuf, 0, 3);
		}
	}

//添加了 writer.flush();  寫入了資料
//刪除了writer.flush(); 添加了 writer.close(); reader.close(); 寫入了資料