IO流:位元組流、字符流、緩沖流
- 一、IO流概論
- 二、位元組流概論
- (一)FileOutputStream
- (二)FileInputStream
- 三、位元組緩沖流概論
- (一)BufferedOutputStream
- (二)BufferedInputStream
- 四、字符流概論
- (一)編碼表
- (二)OutputStreamWriter
- (三)InputStreamReader
- (四)字符流中的編碼解碼問題
- (五)FileWrite 與 FileReader
- 五、字符緩沖流概述
- (一)BufferedWriter
- (二)BufferedReader
一、IO流概論
IO流中所謂的I和O實際上指的 input 和 output, 而流則是指計算機的各個部件之間的的資料流動,
根據資料的傳輸方向,我們可以分為輸入流和輸出流,
而IO流根據處理的資料型別不同,可以分為位元組流、字符流、緩沖流,
而緩沖流也分為位元組緩沖流、字符緩沖流,
(一般來說,我們說的IO流分類是按照資料型別來分的)
IO流就是用來處理設備資料傳輸問題的,常見的應用有:檔案復制、檔案上傳、檔案下載等等,
那么什么情況下使用位元組流?在什么情況下使用字符流呢?
- 人類讀得懂的東西,例如存有一篇文章的txt檔案,這些里面的內容我們可以看懂,這樣就使用字符流,
- 人類讀不懂的東西,例如一張圖片,用文本格式打開會看到一群亂碼,因此傳輸圖片等這種東西就可以使用位元組流,
- 如果不確定使用位元組流還是字符流,那么我們可以使用位元組流,
需要注意的是用IO流對檔案進行操作時,最后面一定要記得關閉檔案!!!
二、位元組流概論
說起位元組流,不得不提起兩個類 InputStream 和 OutputStream, 這兩個類分別是輸入位元組流的所有類的超類和輸出位元組流的所有類的超類,
但因這兩個超類均為抽象類,因此這兩個超類無法實體化,只能依靠其子類實體化,
- InputStream 的子類:AudioInputStream , ByteArrayInputStream , FileInputStream , FilterInputStream , InputStream , ObjectInputStream , PipedInputStream , SequenceInputStream , StringBufferInputStream
- OutputStream的子類:ByteArrayOutputStream , FileOutputStream , FilterOutputStream , ObjectOutputStream , OutputStream , PipedOutputStream
子類名特點:子類名稱都是以其父類名作為子類名的后綴,
本文主要講述 FileInputStream 和 FileOutputStream ,
(一)FileOutputStream
FileOutputStream 是檔案輸出流是用于將資料寫入File或FileDescriptor的輸出流,
要學習這個類的使用,首先第一步先從構造方法開始,
常用構造方法如下:
| Constructor | 描述 |
|---|---|
FileOutputStream(String name) | 創建檔案輸出流以指定的名稱寫入檔案, |
FileOutputStream(String name, boolean append) | 創建檔案輸出流以指定的名稱寫入檔案, |
FileOutputStream 常用的方法如下:
| Modifier and Type | 方法 | 描述 |
|---|---|---|
void | close() | 關閉此檔案輸出流并釋放與此流相關聯的任何系統資源, |
void | write(byte[] b) | 將 b.length位元組從指定的位元組陣列寫入此檔案輸出流, |
void | write(byte[] b, int off, int len) | 將 len位元組從指定的位元組陣列開始,從偏移量 off開始寫入此檔案輸出流, |
void | write(int b) | 將指定的位元組寫入此檔案輸出流, |
package Stream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamDemo {
public static void main(String[] args) throws IOException {
//創建位元組輸出流物件
FileOutputStream fos = new FileOutputStream("IO\\fos.txt");
/*
* 創建物件的代碼實作了三步:
* 1、呼叫系統功能創建檔案
* 2、創建位元組輸出流物件
* 3、讓位元組輸出流物件指向創建好的檔案
* */
byte[] bys = "Hello".getBytes();
//第一種寫入方式,結果是寫入Hello
fos.write(bys);
//第二種寫入方式,結果是寫入ello
fos.write(bys, 1, bys.length - 1);
//第三種寫入方式,結果是寫入a
fos.write(97);
fos.close();
//這個很重要,一定要關閉輸入流
}
}
通過這代碼的執行結果,我們可以發現兩個事情
- 使用IO流時不僅僅需要呼叫IO包,并且還存在例外,需要對例外拋出或者處理程式才能編譯通過
- 如果要操作的檔案不存在的時候,系統將自動創建檔案,并且如果檔案存在,那么每一次輸入的資料都會被覆寫,那么有沒有一種方法是不會覆寫的呢?
首先第二個問題:
很顯然,想要不覆寫之前的內容,只需要在構造方法中進行修改即可
FileOutputStream(String name, boolean append) 在這個構造方法中,若append為true, 那么對檔案寫入資料時候,將不再對原來的資料進行覆寫,
解決對追加寫入資料的問題后,興沖沖再去對檔案進行追加寫入資料后,可能會發現一個問題,為啥寫入的資料都是一行的呢?寫入的操作中怎么完成換行的操作呢??
要解決這個問題就得先清楚每個系統是如何實作換行的!!!
- window:\r\n
- Linux:\n
- max:\r
因此只需要在追加寫入的資料的最后面加入換行的字符即可完成追加寫入并且換行的操作!
再說說例外這個問題
如果我們選擇的是拋出IOException,那么是沒有什么值得注意的,但是在實際開發中,我們往往是要處理這個問題,因此需要使用try …catch…來解決例外,
package Stream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamDemo01 {
public static void main(String[] args) {
try{
FileOutputStream fos = new FileOutputStream("IO\\fos.txt");
fos.write("Hello".getBytes());
fos.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
如果這樣處理例外的話,不難發現一個問題,如果在進行write動作的時候出現了 IOException ,那么程式將會執行catch這段代碼,抓住這個例外并處理;
因此write動作后面的fos.close();可能將不會被執行,這樣導致的后果就是這個位元組流沒有被關閉,最后可能導致資料損失,
故這個**fos.close();**不應該放在write動作后面,這時候要引入一個關鍵詞finally;
finally:在例外處理時提供finally塊來執行所有清楚操作,比如說釋放資源,
因此代碼應改為如下更為合理:
package Stream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamDemo01 {
public static void main(String[] args) {
FileOutputStream fos = null;
try{
fos = new FileOutputStream("IO\\fos.txt");
fos.write("Hello".getBytes());
}catch (IOException e){
e.printStackTrace();
}finally {
try {
fos.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
(二)FileInputStream
FileInputStream用于讀取諸如影像資料的原始位元組流,同樣,要學習這個類的使用,首先第一步先從構造方法開始,
常用構造方法如下:
| Constructor | 描述 |
|---|---|
FileInputStream(File file) | 通過打開與實際檔案的連接來創建一個 FileInputStream ,該檔案由檔案系統中的 File物件 file命名, |
FileInputStream(String name) | 通過打開與實際檔案的連接來創建一個 FileInputStream ,該檔案由檔案系統中的路徑名 name命名, |
FileInputStream 常用方法如下:
| Modifier and Type | 方法 | 描述 |
|---|---|---|
void | close() | 關閉此檔案輸入流并釋放與流相關聯的任何系統資源, |
int | read() | 從該輸入流讀取一個位元組的資料, |
int | read(byte[] b) | 從該輸入流讀取最多 b.length個位元組的資料到一個位元組陣列, |
int | read(byte[] b, int off, int len) | 從該輸入流讀取最多 len個位元組的資料到位元組陣列, |
package Stream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStreamDemo01 {
public static void main(String[] args) throws IOException {
//創建輸入流物件
FileInputStream fis = new FileInputStream("IO\\fos.txt");
/*
檔案內容:
Hello
World
Java
*/
//第一種讀取資料的方法(一次只讀一個位元組資料)
int by;
while ((by = fis.read()) != -1){
System.out.print((char)by);
}
//第二張讀取資料的方法
byte[] bys = new byte[1024];
int len;
while((len = fis.read(bys)) != -1){
//String構造方法
//String?(byte[] bytes, int offset, int length) 通過使用平臺的默認字符集解碼指定的位元組子陣列來構造新的 String ,
System.out.print(new String(bys, 0, len));
}
fis.close();
}
}
通過位元組流讀取檔案資料是一個重復的操作,因此我們可以使用一個回圈進行操作,這個回圈的關鍵就在于控制回圈的條件,在read方法中,如果沒有更多的資料,因為檔案的結尾已經到達, 那么則會回傳-1 ;否則從該輸入流讀取最多bys.length個位元組的資料作為位元組陣列,
用一個len變數接受回傳的數值,如果長度不為-1那么則列印出資料,以此來作為回圈的約束條件,
三、位元組緩沖流概論
位元組緩沖流主要有兩個:BufferedOutputStream 和 BufferedInputStream
- BufferedOutputStream : 該類實作緩沖輸出流, 通過設定這樣的輸出流,應用程式可以向底層輸出流寫入位元組,而不必為寫入的每個位元組導致底層系統的呼叫;
- BufferedInputStream :創建BufferedInputStream 將會創建一個內部緩沖陣列,當從流讀取或跳過位元組時,內部緩沖區將根據需要從所包含的輸入流重新填充,一次很多個位元組,
使用位元組緩沖流物件的時候,會創建一個緩沖數值,通過緩沖陣列進行讀和寫,從而減少IO次數,進而提高讀寫的效率,講白了IO就像送快遞,位元組流就是快遞小哥一次只帶一個快遞,但是緩沖流就是快遞小哥用車來運輸快遞,一次運輸多個快遞,效率大大提高,
(一)BufferedOutputStream
構造方法如下:
| Constructor | 描述 |
|---|---|
BufferedOutputStream(OutputStream out) | 創建一個新的緩沖輸出流,以將資料寫入指定的底層輸出流, |
BufferedOutputStream(OutputStream out, int size) | 創建一個新的緩沖輸出流,以便以指定的緩沖區大小將資料寫入指定的底層輸出流, |
從 BufferedOutputStream 構造方法可以知道,傳遞過去的引數是 OutputStream型別的,因此要使用緩沖輸出流之前先要創建一個位元組輸出流FileOutputStream物件,
常用的方法如下:
| Modifier and Type | 方法 | 描述 |
|---|---|---|
void | flush() | 重繪緩沖輸出流, |
void | write(byte[] b, int off, int len) | 從偏移量 off開始的指定位元組陣列寫入 len位元組到緩沖輸出流, |
void | write(int b) | 將指定的位元組寫入緩沖的輸出流, |
這其中的write方法和FileOutputStream中的write方法用法大體上一樣,
而flush()方法則是實作了一個重繪功能,因為輸入的資料是存在一個緩沖區里面,若想吧緩沖區的資料存放到檔案中,那么就需要用到flush方法,它可以重繪緩沖輸入流,實作此功能,
package Stream;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedOutputStreamDemo01 {
public static void main(String[] args) throws IOException {
//創建位元組輸出緩沖流物件
BufferedOutputStream bof = new BufferedOutputStream(new FileOutputStream("IO\\bof.txt"));
//寫入資料
bof.write("Hello\r\n".getBytes());
bof.write("World\r\n".getBytes());
//重繪緩沖流
bof.flush();
//釋放資源
bof.close();
}
}
改程式的運行結果是將Hello和World分別寫進檔案的兩行,這時候就會感覺奇怪了,不是說要不說明是否追加寫入的話默認不追加寫入嗎?那為什么這里還能寫進兩個字串?
這是檔案關閉(執行close方法)后再打開檔案寫入資料,原來資料保存,那才叫追加寫入,但是這里從頭到尾檔案只打開一次,所以不是追加寫入,只是在打開一個檔案的情況下,進行寫入資料,
(二)BufferedInputStream
構造方法如下:
| Constructor | 描述 |
|---|---|
BufferedInputStream(InputStream in) | 創建一個 BufferedInputStream并保存其引數,輸入流 in供以后使用, |
BufferedInputStream(InputStream in, int size) | 創建具有指定緩沖區大小的 BufferedInputStream ,并保存其引數,輸入流 in供以后使用, |
同樣的,BufferedInputStream 的構造方法傳遞的引數型別是 InputStream 型別的資料,因此在創建這個BufferedInputStream 物件時,需要先構造一個 FileInputStream 物件,然后作為BufferedInputStream 物件構造方法的引數,
常用方法如下:
| Modifier and Type | 方法 | 描述 |
|---|---|---|
void | close() | 關閉此輸入流并釋放與流相關聯的任何系統資源, |
int | read() | 見 read法 InputStream的一般合同, |
int | read(byte[] b, int off, int len) | 從給定的偏移開始,將位元組輸入流中的位元組讀入指定的位元組陣列, |
這些常用的方法的使用方法,與FileInputStream類中的沒啥區別,用法大致相同
package Stream;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class BufferedInputStreamDemo01 {
public static void main(String[] args) throws IOException {
//創建位元組緩沖輸入流物件
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("IO\\bof.txt"));
//一次讀取一個位元組資料
int by;
while ((by = bis.read()) != -1){
System.out.print((char) by);
}
//一次讀取一個位元組陣列
byte[] bys = new byte[1024];
int len;
while ((len = bis.read(bys)) != -1) {
System.out.println(new String(bys, 0, len));
}
bis.close();
}
}
四、字符流概論
為什么會出現字符流呢?
是因為如果讀取文本資料時,如果文本資料中有中文,而中文是由多個位元組構成的,那么位元組流通過讀取一個一個位元組輸出的方式顯然是不行,這樣輸出的結果會是一串亂碼,
此時字符流的優勢就展現出來了,而字符流 = 位元組流 + 編碼表;
一個漢字在不同的編碼的存盤是不一樣的
- 如果是GBK編碼,占用2個位元組
- 如果是UTF-8編碼,占用3個位元組
由前面我們可以知道,String類中的getBytes方法可以使用平臺的默認字符集將該 String編碼為一系列位元組,將結果存盤到新的位元組陣列中**,其中IDEA中默認的編碼是UTF-8,**因此用它來解碼一個漢字,則會得到三個位元組,
String類中的getBytes方法是一個多載的方法,具體如下:
| Modifier and Type | 方法 | 描述 |
|---|---|---|
byte[] | getBytes() | 使用平臺的默認字符集將該 String編碼為一系列位元組,將結果存盤到新的位元組陣列中, |
byte[] | getBytes(String charsetName) | 使用命名的字符集將該 String編碼為一系列位元組,將結果存盤到新的位元組陣列中, |
因此我們可以使用第二個多載了的getBytes方法進行指定編碼解碼漢字
package Stream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
public class getBytesDemo {
public static void main(String[] args) throws UnsupportedEncodingException {
String s = "中國";
byte[] bys01 = s.getBytes();
byte[] bys02 = s.getBytes("GBK");
System.out.println("UTF-8解碼結果:" + Arrays.toString(bys01));
System.out.println("GBK解碼結果:" + Arrays.toString(bys02));
/*
運行結果:
UTF-8解碼結果:[-28, -72, -83, -27, -101, -67]
GBK解碼結果:[-42, -48, -71, -6]
*/
}
}
但是我們使用位元組流也可以復制文本檔案,文本檔案也會有中文,但是卻沒問題,這是為什么呢?
原因是最終底層操作會自動進行位元組拼接成中文,但是是如何識別是中文的呢?
其實,漢字在存盤的時候,無論選擇哪種編碼存盤,其第一個位元組都是負數,因此只要是位元組是負數就說明它是漢字,
(一)編碼表
字符流涉及到編碼方式,因此需要了解到編碼表
基礎知識
- 計算機中存盤的資訊都是用二進制表示的;
- 按照某種規則,將字符存盤到計算機中,稱為編碼;
- 將存盤在計算機中的二進制數按照某種規則決議顯示出來,稱為解碼;
字符集
字符集是一個系統支持的所有字符的集合,包括國家文字,圖形符號,數字等;
常見的字符集有:ASCII字符集、GBXXXX字符集、Unicode字符集
各個國家為了符合自己國家語言,然后設計出了一套屬于自己國家的字符集,但是其他國家并沒有它這套字符集,那么其他國家解碼豈不是都是亂碼???
其實并不然Unicode字符集的出現解決了這個現象,其中最為常用的就是UTF-8編碼,互聯網工程作業小組(IETF)要求所有互聯網協議都必須支持UTF-8編碼,它使用一至四個位元組為每個字符編碼,
必須強調的是采用哪種規則編碼,就必須采用對應規則解碼,否則會出現亂碼!!!!
(二)OutputStreamWriter
Writer:位元組輸出流的抽象類
而 OutputStreamWriter 是繼承 Writer 的子類
其構造方法如下:
| Constructor | 描述 |
|---|---|
OutputStreamWriter(OutputStream out) | 創建一個使用默認字符編碼的OutputStreamWriter, |
OutputStreamWriter(OutputStream out, String charsetName) | 創建一個使用命名字符集的OutputStreamWriter, |
常用方法如下:
| Modifier and Type | 方法 | 描述 |
|---|---|---|
void | close() | 關閉流,先重繪, |
void | flush() | 重繪流, |
void | write(char[] cbuf, int off, int len) | 寫入字符陣列的一部分, |
void | write(int c) | 寫一個字符 |
void | write(String str, int off, int len) | 寫一個字串的一部分, |
這些方法的使用方法大體上與位元組流差不多,值得注意的是write方法傳遞的引數可以直接傳遞字符陣列,不用先解碼成byte陣列再傳遞過去,
package Stream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class OutputStreamWriterDemo01 {
public static void main(String[] args) throws IOException {
//創建物件
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("IO\\osw.txt"));
//1.寫入字符
osw.write('a');
//2.寫入字串
osw.write("\r\n中國\r\n");
osw.flush();
//3.字符陣列
char[] ch = {'a', 'b', 'c'};
osw.write(ch);
osw.write(ch, 0, 1);
osw.flush();
//4.寫入一部分
osw.write("HelloWorld", 0, 5);
osw.flush();
osw.close();
}
}
需要注意的是:OutputStreamWriter的中的close有點特別,它是在關閉之前會先重繪,也就是說在執行釋放資源的之前,其會先主席那個flush方法,達到先把資料存盤在文本資訊的結果再釋放資源,
(三)InputStreamReader
Reader:位元組輸入流的抽象類
InputStreamReader 是繼承了 Reader 的子類
其構造方法如下:
| Constructor | 描述 |
|---|---|
InputStreamReader(InputStream in) | 創建一個使用默認字符集的InputStreamReader, |
InputStreamReader(InputStream in, String charsetName) | 創建一個使用命名字符集的InputStreamReader, |
常用方法如下:
| Modifier and Type | 方法 | 描述 |
|---|---|---|
void | close() | 關閉流并釋放與之相關聯的任何系統資源, |
int | read() | 讀一個字符 |
int | read(char[] cbuf, int offset, int length) | 將字符讀入陣列的一部分, |
package Stream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
public class InputStreamReaderDemo01 {
public static void main(String[] args) throws IOException {
//創建物件
InputStreamReader isr = new InputStreamReader(new FileInputStream("IO\\osw.txt"));
//讀一個字符資料資料
int ch;
while ((ch = isr.read()) != -1){
System.out.print((char) ch);
}
//一次讀一個字符陣列資料
char[] chs = new char[1024];
int len;
while ((len = isr.read(chs)) != -1){
System.out.println(new String(chs));
}
}
}
InputStreamReader的常用方法的使用大多與位元組流類似
(四)字符流中的編碼解碼問題
在IDEA中默認的編碼解碼都是使用UTF-8編碼來實作的
但是如果我們構建字符輸出流物件 OutputStreamWriter 的時候指定使用其他字符集編碼,比如指定使用GBK編碼,這是后我們打開已經寫入資料的txt檔案中,我們會發現出現了亂碼情況,這是為什么呢???
這是因為txt默認使用UTF-8編碼進行解碼,但是編碼是使用GBK進行編碼的,因此肯定會出現亂碼情況,
這時候我們讀取資料顯示在螢屏上的時候,如果我們創建字符輸入流物件 InputStreamReader 的時候,沒有指定使用GBK編碼進行解碼,那么它會默認使用UTF-8編碼進行解碼,進而出現亂碼的情況,若我們需要顯示出正常的內容而不是亂碼,我們需要執行GBK編碼進行決議,
總而言之,我們規定了使用哪種規則進行編碼,就要使用哪種規則進行決議,否則會亂碼!!!!
(五)FileWrite 與 FileReader
在處理現實問題中,比如復制一個java檔案,如果其中不涉及編碼問題,即不需要指定某種編碼規則進行編碼和解碼,那么為了簡便,我們可以使用 OutputStreamWriter 的子類 FileWrite 、 InputStreamReader 的子類 FileReader ;
但是如果一旦涉及到編碼問題,還得使用 OutputStreamWriter 和 InputStreamReader 進行處理檔案!!!
FileWrite 的構造方法如下:
| Constructor | 描述 |
|---|---|
FileReader(File file) | 創建一個新的 FileReader ,給出 File讀取, |
FileReader(String fileName) | 創建一個新的 FileReader ,給定要讀取的檔案的名稱, |
由于 FileWrite 繼承了 OutputStreamWriter ,所以 FileWrite 的常用方法的型別與用法與OutputStreamWriter一致,
FileReader 的構造方法如下:
| Constructor | 描述 |
|---|---|
FileWriter(File file) | 給一個File物件構造一個FileWriter物件, |
FileWriter(File file, boolean append) | 給一個File物件構造一個FileWriter物件, |
FileWriter(String fileName) | 構造一個給定檔案名的FileWriter物件, |
FileWriter(String fileName, boolean append) | 構造一個FileWriter物件,給出一個帶有布林值的檔案名,表示是否附加寫入的資料, |
同樣,由于 FileReader 繼承了 InputStreamReader ,所以 FileReader 的常用方法的型別與用法與InputStreamReader 一致,
五、字符緩沖流概述
字符緩沖流主要是 BufferedWriter 與 BufferedReader, 兩者分別繼承兩個抽象類 Writer 與 Reader ;
BufferedWriter :將文本寫入字符輸出流,緩沖字符,以提供單個字符,陣列和字串的高效寫入,可以指定緩沖區大小,或者可以接受默認大小,默認足夠打,可用于大多數用途,
BufferedReader:從字符輸入流讀取文本,緩沖字符,以提供字符,陣列和行的高效讀取,可以指定緩沖區大小,或者可以接受默認大小,默認足夠打,可用于大多數用途,
(一)BufferedWriter
BufferedWriter 字符緩沖輸出流的構造方法如下:
| Constructor | 描述 |
|---|---|
BufferedWriter(Writer out) | 創建使用默認大小的輸出緩沖區的緩沖字符輸出流, |
BufferedWriter(Writer out, int sz) | 創建一個新的緩沖字符輸出流,使用給定大小的輸出緩沖區, |
從構造方法可知道,需要傳遞一個 Writer 型別的作為引數過去, 因此在使用字符緩沖輸出流的時候,要先創建一個FileWriter物件,
BufferedWriter 字符緩沖輸出流的常用方法如下:
| Modifier and Type | 方法 | 描述 |
|---|---|---|
void | close() | 關閉流,先重繪, |
void | flush() | 重繪流, |
void | newLine() | 寫一行行分隔符, |
void | write(char[] cbuf, int off, int len) | 寫入字符陣列的一部分, |
void | write(int c) | 寫一個字符 |
void | write(String s, int off, int len) | 寫一個字串的一部分, |
這里面的很多方法都與前面的類似,但是這有一個特有的方法 newLine 方法, 其作用是寫一行行分隔符,也就是換行的意思,
從上面我們可以知道,不同的作業系統的換行符號不一樣,比如window的換行符號是\r\n,但是Linux的換行符號是\n,如果手動添加換行符,如果在不同的系統可能達不到換行的效果,因此,newLine 方法的出現,很好的解決了在不同系統換行的問題!!!
package Stream;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
public class BufferedWriterDemo {
public static void main(String[] args) throws IOException {
//創建字符緩沖流輸出流物件
BufferedWriter bw = new BufferedWriter(new FileWriter("IO\\bw.txt"));
bw.write("Hello");
bw.newLine();//換行
bw.write("World");
bw.close();
}
}
(二)BufferedReader
字符緩沖輸入流 BufferedReader構造方法如下:
| Constructor | 描述 |
|---|---|
BufferedReader(Reader in) | 創建使用默認大小的輸入緩沖區的緩沖字符輸入流, |
BufferedReader(Reader in, int sz) | 創建使用指定大小的輸入緩沖區的緩沖字符輸入流, |
從構造方法可知道,需要傳遞一個 Reader型別的作為引數過去, 因此在使用字符緩沖輸入流的時候,要先創建一個FileReader物件,
BufferedReader字符緩沖輸入流的常用方法如下:
| Modifier and Type | 方法 | 描述 |
|---|---|---|
void | close() | 關閉流并釋放與之相關聯的任何系統資源, |
int | read() | 讀一個字符 |
int | read(char[] cbuf, int off, int len) | 將字符讀入陣列的一部分, |
String | readLine() | 讀一行文字, |
這里面的很多方法都與前面的類似,但是其中有一個readLine的方法,可以一次讀一行文字,然后回傳一個String型別,這個方法十分實用
package Stream;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
//創建物件
BufferedReader br = new BufferedReader(new FileReader("IO\\bw.txt"));
String line;
while ((line = br.readLine()) != null){
System.out.println(line);
}
}
}
readLine方法可以讀一行文字, 一行被視為由換行符(’\ n’),回車符(’\ r’)中的任意一個,緊跟換行符的回車符或通過到達檔案末尾終止(EOF),
一個包含行的內容的字串,不包括任何行終止字符,如果沒有讀取任何字符,如果流的結尾已經到達,則為null ,因此可以使用這個特性作為回圈的約束條件,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/355768.html
標籤:python
上一篇:百寶箱:奇奇怪怪的問題
