java~字節流和字符流
如果要進行文件內容的操作那么必須依靠數據流完成,而數據流分為兩種:
- 字節流:InputStream(字節輸入流)、OutputStream(字節輸出流)
- 字符流:Reader(字符輸入流)、Writer(字符輸出流)
輸入和輸出是針對內存來說的:
- 輸入流:字節(網絡,磁盤)–> 自動轉換為 –>字符(內存);
- 輸出流:字符(內存)–> 自動轉換為–>字節(網絡,磁盤);

區別
字節流與字符流操作的本質區別只有一個:字節流是原生的操作,而字符流是經過處理后的操作。
- 在進行
網絡數據傳輸、磁盤數據所支持的數據類型只有:字節。 - 而所有磁盤中的數據必須先讀取到內存后才能進行操作,而內存中會幫助我們把
字節變為字符。字符更加適合處理中文。
操作流程
不管使用的是字節流還是字符流,其基本的操作流程幾乎是一樣的,以文件操作為例。
- 創建File類對象 ,主要是指明要操作的文件路徑;
- 根據字節流或字符流的子類實例化父類對象 ;
- 進行數據的讀取或寫入操作;
- 關閉流(close());
對于IO操作屬于資源處理,所有的資源處理操作(IO操作、數據庫操作、網絡)最后必須要進行關閉。
字節輸出流:(OutputStream)
字節輸出流主要以操作byte數據為主,觀察java.io.OutputStream類的定義結構:
public abstract class OutputStream implements Closeable, Flushable
OutputStream類實現了Closeable,Flushable兩個接口,這兩個接口中的方法:
- Closeable: public void close() throws IOException;
- Flushable: public void flush() throws IOException;
實例:文件的輸出
public class Demo {
public static void main(String[] args) throws IOException {
//第一步:定義要輸出的文件的File類對象
File file = new File("e:"+File.separator+"hello"+File.separator+"my.txt");
//輸出信息的時候文件可以不存在,但是目錄必須存在
if(!file.getParentFile().exists()) {//父路徑不存在
file.getParentFile().mkdirs();//創建父路徑
}
//第二步:利用OutputStream的子類為父類進行實例化
OutputStream output = new FileOutputStream(file);
//第三步:輸出文字信息
String msg = "富則達濟天下,窮則獨善其身";//字符串
//為了方便輸出需要將字符串變為字節數組
byte data[] = msg.getBytes();//變為字節數組
output.write(data);//輸出數據
output.close();//關閉流
}
}
字節輸入流:(InputStream)
InputStream可以實現數據的讀取操作,在java中InputStream類的定義如下:
public abstract class InputStream implements Closeable
InputStream類中定義有三個數據的讀取操作方法:
- 讀取單個字節:public abstract int read() throws
IOException;
每次執行此方法將讀取當個字節數據,如果已經讀取完成了,那么最后返回-1。 - 讀取數據到字節數組中:public int read(byte b[]) throws IOException.最常用方法
每次講數據讀取到數組之中,那么會返回一個讀取長度的數據,如果沒有數據則返回的長度為-1,可是要考慮兩種情況:要讀取的內容大于開辟的數組內容:長度就是整個數組的長度。要讀取的內容小于開辟數組的內容,
長度就是全部最后的內容長度,數組裝不滿。 - 讀取部分內容到字節數組中:public int read(byte b[], int off,int len) throws IOException
每次讀取內容到部分字節數組,只允許讀取滿限制的數組的字節個數。此方法依然會返回讀取的長度。
InputStream是一個抽象類,所以要進行文件的讀取使用FileInputStream子類,子類定義的構造方法如下:
構造方法:public FileInputStream(File file) throws FileNotFoundException.
@SuppressWarnings("unused")
public class Demo {
public static void main(String[] args) throws IOException {
//第一步:定義要輸出的文件的File類對象
File file = new File("e:"+File.separator+"hello"+File.separator+"my.txt");
//第二步:實例化InputStream
InputStream input = new FileInputStream(file);
//實現數據的讀取操作
byte data[] = new byte[1024];
int len = input.read(data);//將數據讀取到數組之中
System.out.println("讀取的內容【" +new String(data,0,len)+"】");
//第四步關閉輸入流
input.close();
}
}
字符輸出流:(Writer)
Writer是進行字符輸出操作使用的類,這個類屬于抽象類,觀察定義:
public abstract class Writer implements Appendable, Closeable, Flushable
這個Writer類可以直接輸出字符串:public void write(String str) throws IOException
Writer是一個抽象類,要進行文件字符流操作,其構造方法為:
@SuppressWarnings("unused")
public class Demo {
public static void main(String[] args) throws IOException {
//第一步:定義要輸出的文件的File類對象
File file = new File("e:"+File.separator+"hello"+File.separator+"my.txt");//你的路徑
if(!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
Writer out = new FileWriter(file);
String str = "一定要好好學習,天天向上。。。";
out.write(str);
out.close();
}
}
雖然Writer類提供有字符數組的輸出操作能力,但是從本質上來講使用Writer類就意味著要執行字符串的直接輸出。
字符流最適合操作中文,但并不意味著字節流就無法操作中文。
字符輸入流:(Reader)
Reader一定是一個抽象類,其定義為:
public abstract class Reader extends Object implements Readable,Closeable
在Reader類中也提供有一系列的read()方法。
- 數據的讀取:public int read(char[] cbuf) throws IOException。
范例:數據的讀取
@SuppressWarnings("unused")
public class Demo {
public static void main(String[] args) throws IOException {
//第一步:定義要輸出的文件的File類對象
File file = new File("e:"+File.separator+"hello"+File.separator+"my.txt");//你的路徑
if(file.exists()) {
Reader in = new FileReader(file);
char data[] = new char[1024];
int len = in.read(data);//向字符數組保存數據,返回長度。
System.out.println(new String(data,0,len));
in.close();
}
}
}
字節流與字符流的區別
首先必須要明確一點,通過任何終端(網絡、文件)讀取或者輸出的數據都一定是字節,字符是經過內存處理后的數據。
字符輸入:字節(磁盤)–> 自動轉換為 –>字符(內存);
字符輸出:字符(內存)–> 自動轉換為–>字節(磁盤);
在利用字符流輸出的時候,所有的內容實際上都只是輸出到了緩沖區中(內存)。在使用close()方法關閉的時候會將我們緩沖區的數據進行輸出,如果沒有關閉,那么就將無法進行輸出,此時可以利用flush()方法進行強制的輸出。
字符使用到了緩沖區,而字節流沒有使用到緩沖區。
如果處理中文使用字符流,其他的任何數據都使用字節流。
浙公網安備 33010602011771號