前面我們學習了IO流的字節輸入輸出流,可以幫助我們很好地讀取和輸入一些數據,但是當我們想讓它更快的讀取和輸出出來,有沒有更加高效的流呢?
這時就需要我們的字節緩衝輸入流(BufferedInputStream)和字節緩衝輸出流(BufferedOutputStream)
BufferedOutputStream:
字節緩衝輸出流:
構造方式:
(第一種開發中使用多) public BufferedOutputStream(OutputStream out):採用的默認的緩衝區大小(足夠大了) ,來構造一個字節緩衝輸出流對象
public BufferedOutputStream(OutputStream out,int size):指定size緩衝區大小構造緩衝輸出流對象
寫數據的方式:
一次寫一個字節
write(int by)
一次寫一個字節數組的一部分
write(byte[] b, int off, int len)
package com.westos.BufferedStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedOutputStreamDome {
/**
* @param args
* @throws IOException
* 使用字節緩衝輸出流去給文本中寫入數據,這樣比普通字節輸出流更加高效
*/
public static void main(String[] args) throws IOException {
//創建字節緩衝輸出流對象
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("file.txt"));
//寫數據
bos.write("迪麗熱巴最美麗".getBytes());
//關閉資源
bos.close();
}
}
BufferedInputStream:
構造方式:
public BufferedInputStream(InputStream in):默認緩衝區大小構造緩衝輸入流對象
public BufferedInputStream(InputStream in,int size):指定緩衝區大小構造緩衝輸入流對象
寫數據的方式:
public int read()
public int read(byte[] b,int off,int len)
在使輸入流的時候,
兩種方式讀取(一次讀取一個字節/一次讀取一個字節數在),只能用一種方式,否則,會出現錯誤!
package com.westos.BufferedStream;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class BufferedInputStreamDome {
public static void main(String[] args) throws IOException {
//創建字節緩衝輸入流對象
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("file.txt"));
/* //一次讀取一個字節
int len=0;
while((len=bis.read())!=-1) {
System.out.print((char)len);
}
bis.close();
*/
//一次讀取一個數組
byte[] bys=new byte[1024];
int len=0;
while((len=bis.read(bys))!=-1) {
String str = new String(bys,0,len);
System.out.println(str);
}
bis.close();
}
}
我們前面瞭解到IO流按流的類型分爲字節流和字符流,我們已經瞭解了字節流,接下來讓我們再看看字符流:
字符流的引入:
package com.westos.BufferedStream;
import java.io.IOException;
import java.util.Arrays;
/**
* @author 傑哥
*編碼和解碼的時候,其中的格式一定要相同,不能前後不一
*否則就會出現亂碼的現象
*系統默認的編碼格式是gbk
*gbk中:一箇中文對應兩個字節
*utf-8中:一個字節對應三個字節
*/
public class StringDome {
public static void main(String[] args) throws IOException {
//編碼
//定義一個字符串
String str="迪麗熱巴最美";
//這裏的"gbk"可以不寫,因爲系統默認是編碼格式是"gbk",但是當你用utf-8格式時,必須的寫好,下面解碼中的格式也必須統一utf-8
byte[] bys = str.getBytes("gbk");
//將字節數組轉變成字符串
System.out.println(Arrays.toString(bys));
System.out.println("-------------------------------------");
//解碼
//這裏String裏面的"gbk"也可以不寫,同樣是默認的
String st=new String(bys,"gbk");
System.out.println(st);
}
}
運行結果:
[-75, -49, -64, -10, -56, -56, -80, -51, -41, -18, -61, -64]
-------------------------------------
迪麗熱巴最美
當我們使用字節流去讀取有中文的數據時,會出現亂碼的現象,這就是前後的格式不同
所以,就需要我們的字符流了
字符流
字符流分爲字符輸出流(writer)和字符輸入流(reader),因爲字符流都是抽象類,所以不能創建對象,因此需要它的子類來創建對象
例如:
package com.westos.WritreReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
/**
* @author 傑哥
*將文本中的內容輸出到控制檯上
*/
public class WriterReaderDome {
public static void main(String[] args) throws Exception {
//創建字符輸入流
InputStreamReader isr=new InputStreamReader(new FileInputStream("file.txt"),"gbk");
//一次獲取一個字節
// int by=0;
// while((by=isr.read())!=-1) {
// System.out.print((char)by);
// }
//一次讀取一個數組
char[] bys=new char[1024];
int len=0;
while((len=isr.read(bys))!=-1) {
System.out.println(new String(bys,0,len));;
}
//關閉資源
isr.close();
}
}
從上述代碼中我們可以看出創建字符輸入流的代碼過於繁瑣,因此我們可以尋找一個便捷類(FileReader)來代替它
例如:
字符輸入流讀數據的方法:
int read(char[] chs):讀取一個字符數組
int read():讀取單個字符
package com.westos.WritreReader;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDome {
public static void main(String[] args) throws IOException {
//創建字符輸入流
FileReader fr=new FileReader("file.txt");
/*
//一次讀取一個字節
int len=0;
while((len=fr.read())!=-1) {
System.out.print((char)len);
}
*/
//一次讀取一個數組
char[] ch=new char[1024];
int len=0;
while((len=fr.read(ch))!=-1) {
System.out.println(new String(ch,0,len));
}
//關閉資源
fr.close();
}
}
這樣可以看出便捷類的代碼相對簡單些,在字符輸入流有(FileReader便捷類),那麼字符輸出流也有(FileWeiter便捷類)
下面我們看看怎麼將文件中的數據複製到另一個文件中去?
例如:
package com.westos.WritreReader;
import java.io.FileReader;
import java.io.FileWriter;
/**
* @author 傑哥
*需求:進行文本的copy
* 使用便捷類進行以下操作
* 將文本中的數據copy到另一個文本中
*/
public class TextDome {
public static void main(String[] args) throws Exception {
//創建源文件對象和目的地文件對象
FileReader fr=new FileReader("file.txt");
FileWriter fw=new FileWriter("f.txt");
//一次讀取一個數組
char[] ch=new char[1024];
int len=0;
//一邊讀取一邊寫
while((len=fr.read(ch))!=-1) {
fw.write(ch,0,len);
}
//關閉資源
fr.close();
fw.close();
}
}
字符輸出流寫數據的功能:
public void write(int c):寫單個字符
public void write(char[] cbuf):寫字符數組
public abstract void write(char[] cbuf, int off, int len):寫字符數組的一部分
public void write(String str):寫字符串
public void write(String str,int off, int len):寫字符串的某一部分
flush和close方法的區別?
close:關閉該流,關閉該流對象以及它關聯 的資源文件,關閉之後,不能再對流對象進行操作了,否則會有異常
flush:刷新該流,爲了防止一些文件(圖片文件/音頻文件),缺失,或者沒有加載到流對象中,刷新了該流,還是可以流對象進行操作
例如:
package com.westos.WritreReader;
import java.io.FileWriter;
public class FileWriterDome {
public static void main(String[] args) throws Exception {
//創建字符輸出流
FileWriter fw=new FileWriter("a.txt");
//public void write(int c):寫單個字符
fw.write('a');
//public void write(char[] cbuf):寫字符數組
char[] ch= {'a','b','c','d'};
fw.write(ch);
//public abstract void write(char[] cbuf, int off, int len):寫字符數組的一部分
fw.write(ch,0,3);
//public void write(String str):寫字符串,這個用的最多
String str="RNG奪冠了";
fw.write(str);
//public void write(String str,int off, int len):寫字符串的某一部分
fw.write(str,0,3);
//對字符流進行刷新
fw.flush();
fw.close();
}
}
字節流中有更高效的字節緩衝流,那麼在字符流中依然有高效的字符緩衝流
接下來讓我們先看看字符緩衝輸出流(BufferedWriter)
BufferedWriter:字符緩衝輸出流
構造方法:
BufferedWriter(Writer out) :默認緩衝區大小構造字符緩衝輸出流對象
BufferedWriter(Writer out,int size):指定緩衝區大小
例如:
package com.westos.BufferedDome;
import java.io.BufferedWriter;
import java.io.FileWriter;
public class BufferedWriterDome {
public static void main(String[] args) throws Exception {
//創建字符緩衝輸出流
BufferedWriter bw=new BufferedWriter(new FileWriter("b.txt"));
//寫入數據
bw.write(new String("迪麗熱巴"));
bw.write(new String("最美"));
//刷新流並關閉,記住刷新的方法一定要寫在關閉方法之前
bw.flush();
bw.close();
}
}
BufferedReader:字符緩衝輸入流
構造方法:
public BufferedReader(Reader in)創建一個使用默認大小輸入緩衝區的緩衝字符輸入流。
public BufferedReader(Reader in, int sz)創建一個使用指定大小輸入緩衝區的緩衝字符輸入流。
例如:
package com.westos.BufferedDome;
import java.io.BufferedReader;
import java.io.FileReader;
public class BufferedReaderDome {
public static void main(String[] args) throws Exception {
//創建字符緩衝輸入流
BufferedReader br=new BufferedReader(new FileReader("file.txt"));
//直接一個數組的讀取
char[] ch=new char[1024];
int len=0;
while((len=br.read(ch))!=-1) {
System.out.println(new String(ch,0,len));
}
//關閉資源
br.close();
}
}