一、流的分類
1、按照操作數(shù)據(jù):字節(jié)流、字符流。
2、按照流向:輸入流、輸出流。
二、IO流常用的基類
1、字節(jié)流的抽象基類
InputStream : 字節(jié)輸入流
OutputStream: 字節(jié)輸出流
BufferedInputStream :帶緩沖區(qū)的字節(jié)輸入流。
BufferedOutputStream:帶緩沖區(qū)的字節(jié)輸出流。
2、字符流的抽象基類
Reader :字符輸入流
Writer :字符輸出流
BufferedReader:帶緩沖區(qū)的字符輸入流。
BufferedWriter:帶緩沖區(qū)的字符輸出流。
注意:由這四個(gè)類派生出來的子類名稱都是以其父類父類名作為子類名后綴的。
例如: InputStream 的子類FileInputStream.
Reader 的子類FileReader
3、字節(jié)流和字符流的轉(zhuǎn)換。
InputStreamReader : 字節(jié)流通向字符流的通道,繼承自Reader。
OutputStreamWriter: 字符流通向字節(jié)流的通道,繼承自Writer。
三、字符流
1、FileWriter基本使用
public static void main(String[] args)
{
// 創(chuàng)建一個(gè)文本輸入對(duì)象,該對(duì)象一旦被初始化就要指明操作的文件。
// 該文件會(huì)被創(chuàng)建子啊指定目錄下,如果存在,則會(huì)覆蓋。
// 目的:明確數(shù)據(jù)存放的地方。
FileWriter fw = new FileWriter("1.txt");
// 調(diào)用Write()方法將字符寫入到流中。
f.write("abcde");
// 刷新流對(duì)象中的數(shù)據(jù)到緩沖區(qū)。
f.flush();
// 關(guān)閉流資源,同時(shí)會(huì)自動(dòng)刷新流。
f.close();
}
FileWriter構(gòu)造方法
備注:throws IOException
1、 FileWriter(File file);
2、 FileWriter(File file,boolean append);
3、 FileWriter(String filepath);
4、 FileWriter(String filepath,boolean append);
2、IO異常處理標(biāo)準(zhǔn)格式
public static void main(String[] args){
FileWriter fw = null;
try{
fw = new FileWriter("1.txt");
fw.write("abc");
}catch(IOException e){
e.printStackTrace();
}finally{
try{
if (fw != null){
fw.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
}
3、FileReader基本使用
public static void main(String[] args){
// 創(chuàng)建文件讀取流對(duì)象,并和指定名稱的文件相關(guān)聯(lián)。
// 文件必須存在,否則:FileNotFoundException;
FileReader fr = new FileReader("1.txt");
// 使用read()方法進(jìn)行讀取數(shù)據(jù)
int ch;
while((ch = fr.read()) != -1){
System.out.println("數(shù)據(jù) : " + ch);
}
// 關(guān)閉流
fr.close();
}
FileReader 相關(guān)方法
一、構(gòu)造方法 : throws IOException
1、 FileReader(File file);
2、 FileReader(String filename);
二、其他方法
1、getEncoding():返回此流所使用的字符編碼名稱。
4、BufferedWriter基本使用
緩沖區(qū)的作用:提高流的操作效率。因此必須有流緩沖區(qū)才有意義。
示例代碼 :
public static void main(String[] args){
// 創(chuàng)建一個(gè)字符寫入流。
FileWriter fw = new FileWriter("1.txt");
// 加入緩沖技術(shù),提高流的效率。
BufferedWriter bufw = new BufferedWriter(fw);
// 寫入數(shù)據(jù)
for (int i = 0 ;i < 5 ;i ++){
bufw.writer("abnc");
bufw.newLine();// 換一行。
bufw.flush();// 刷新數(shù)據(jù)流
}
// 關(guān)閉緩沖區(qū)、流
bufw.close();
}
BufferedWriter相關(guān)方法
一、構(gòu)造方法
1、BufferedWriter(Writer out);
創(chuàng)建一個(gè)默認(rèn)大小緩沖區(qū)的輸出字符流。
2、BufferedWriter(Writer out,int sz);
創(chuàng)建一個(gè)指定大小緩沖區(qū)的輸出字符流。
throws IllegalArgumentException .when sz < 0;
二、成員方法 : all throws IOException 異常。
1、void close(); 關(guān)閉該流。
2、void flush(); 刷新該流。
3、void newLine(); 寫入一個(gè)行分割父。
4、void write(char[] buff,int off,int len); 寫入字符數(shù)組的某一部分。
5、void write(int ch); 寫入單個(gè)字符。
6、void write(String ss,int off,int len); 寫入字符串的某一部分。
5、BufferedReader基本使用
示例代碼 :
public static void main(String[] args) throws IOException{
FileReader fr = new FileReader("1.txt");
BufferedReader bufr = new BufferedReader(fr);
String line = null;
while((line = bufr.readLine()) != null){
System.out.println("第一行數(shù)據(jù):" + line);
}
bufr.close();
}
BufferedReader相關(guān)方法
一、構(gòu)造方法
1、BufferedReader(Reader in);
2、BufferedReader(Reader in,int sz);
創(chuàng)建一個(gè)指定緩沖區(qū)大小的字符輸出流。throws IllegalArgumentException when sz < 0
二、成員方法。
1、readLine(); 讀取一行文本。
終止條件:回車'\r'、換行'\n' 、 回車后直接加換行。
返回值: 返回包含該行內(nèi)容的字符串,不包含終止符;如果到達(dá)末尾則返回null。
6、文件拷貝代碼
public copyText_buff(){
// 輸入輸出緩沖區(qū)
BufferedReader bufr = null;
BufferedWriter bufw = null;
try{
bufr = new BufferedReader(new FileReader("1.txt"));
bufw = new BufferedWriter(new FileWriter("1_copy.txt"));
String line = null;
while((line = bufr.readLine()) != null){
bufw.Write(line);
bufw.newLine();
bufw.flush();
}
}catch(IOException e){
throw new RuntimeException("創(chuàng)建字符流失敗");
}finally{
try{
if (bufr != null)
bufr.close();
}catch(IOException ee){
throw new RuntimeException("字符寫流關(guān)閉失敗");
}
try{
if (bufw != null)
bufw.close();
}catch(IOException ee){
throw new RuntimeException("字符讀流關(guān)閉失敗");
}
}
}
7、裝飾設(shè)計(jì)模式
裝飾設(shè)計(jì)模式:當(dāng)要對(duì)已有對(duì)象進(jìn)行功能增強(qiáng)時(shí)??梢远x類,將已有對(duì)象傳入,基于
已有的功能、并提供加強(qiáng)功能。自定義的該類成為裝飾類。
裝飾類通常會(huì)通過構(gòu)造方法接收被裝飾的對(duì)象。
8、LineNumberReader基本用法
LineNumberReader是BufferedReader的子類。
示例代碼 :
public lineNumberReaderDemo() throws IOException{
// 構(gòu)建對(duì)象
FileReader fr = new FileReader("1.txt");
LineNumberReader lfr = new LineNumberReader(fr);
// 設(shè)置行號(hào)
lfr.setLineNumber = 100;
// 讀取內(nèi)容和行號(hào)
String line = null;
while((line = lfr.readLine()) != null){
System.out.println(lfr.getLineNumber + " : " + line);
}
// 關(guān)閉流
lfr.close();
}
*方法介紹 : *
一、構(gòu)造方法
LineNumberReader(Reader in);
使用默認(rèn)輸入緩沖區(qū)大小,創(chuàng)建行編號(hào)reader。
LineNumberReader(Reader in,int sz);
使用指定大小的輸入緩沖區(qū),創(chuàng)建行編號(hào)Reader。
throws IllegalArgumentException when sz < 0
二、成員方法
public void setLineNumber(int lineNumber);
設(shè)置當(dāng)前行號(hào)
public int getLineNumber();
獲取當(dāng)前行號(hào)。
9、readLine()的實(shí)現(xiàn)原理
public static void main(String[] args)throws IOException
{
// readLine()底層實(shí)現(xiàn)是使用的數(shù)組,我這使用的是StringBuilder效果是一樣的。
FileReader fr = new FileReader("PersonDemo.java");
LineNumberReader lnr = new LineNumberReader(fr);
String line = null;
lnr.setLineNumber(100);
while((line=lnr.readLine())!=null)
{
System.out.println(lnr.getLineNumber()+":"+line);
}
lnr.close();
}
10、裝飾設(shè)計(jì)模式和繼承的區(qū)別
1、 繼承體系
MyReader // 專門用于讀取數(shù)據(jù)的類。
|--MyTextReader
|--MyBufferedTextReader
|--MyMediaReader
|--MyBufferedMediaReader
|--MyDataReader
|--MyBufferedDataReader
.
.
.
問題就來了,MyReader每次增加一個(gè)子類都要增加一個(gè)相應(yīng)的BufferedReader子類。
造成類的體系過于臃腫。類的擴(kuò)展性很差。
2、裝飾設(shè)計(jì)模式體系
MyReader // 專門用于讀取數(shù)據(jù)的類。
|--MyBufferedReader
|--MyTextReader
|--MyMediaReader
|--MyDataReader
.
.
.
類的擴(kuò)展性強(qiáng)。單獨(dú)描述緩沖內(nèi)容,將需要被緩沖的對(duì)象作為參數(shù)傳遞進(jìn)緩沖區(qū)。優(yōu)化了體系結(jié)構(gòu)。
四、字節(jié)流
字節(jié)流:InputStream、OutputStream。
1、FileOutputStream 基本用法
示例代碼 :*
public static void main(String[] args){
// 創(chuàng)建輸出流對(duì)象
FileOutputStream out = new FileOutputStream("1.txt");
// 輸出數(shù)據(jù)
out.write("abcd".getBytes());
// 關(guān)閉流
out.close();
}
方法介紹 :
一、構(gòu)造方法:
FileOutputStream(File file);
創(chuàng)建一個(gè)指向File的文件輸出流對(duì)象。
FileOutputStream(File file,boolean append);
創(chuàng)建文件輸出流,并指明是否追加內(nèi)容。
FileOutputStream(String filename);
FileOutputStream(String filename,boolean append);
2、FileInputStream基本用法
示例代碼 :
public static void main(String[] args)throws IOException{
FileInputStream in = FileInputStream("1.map");
int ch = 0;
while((ch = in.read()) != -1){
System.out.println("字符 : " + (char)in);
}
in.close();
}
方法介紹 :
一、構(gòu)造方法
1、FileInputStream(File file);
2、FileInputStream(String filename);
二、成員方法
1、public int available();
返回可以不受阻塞地從此文件輸出流中的讀取的字節(jié)數(shù)。
字符流實(shí)現(xiàn)拷貝圖片
public static void main(String[] args){
FileOutputStream out = null;
FileInputStream in = null;
try{
out = new FileOutputStream("copy_1.bmp");
in = new FileInputStream("1.bmp");
byte[] tmp = new byte[1024];
int len = 0;
while((len = in.read(tmp)) != -1){
out.write(tmp,0,len);
}
}catch(IOException e){
throw RuntimeException("流創(chuàng)建失敗");
}finally{
try{
if(in != null)
in.close();
}catch(IOException ee){
throw RuntimeException("輸入流關(guān)閉失敗");
}
try{
if(out != null)
out.close();
}catch(IOException ee){
throw RuntimeException("輸出流關(guān)閉失敗");
}
}
}
3、帶緩沖區(qū)的字節(jié)流
示例代碼 :
public void copy_1() throws IOException{
BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream("copy_1.mp3"));
BufferedInputStream fis = new BufferedInputStream(new FileInputStream("1.mp3"));
int ch = 0;
while((ch = fis.read()) != -1){
fos.write(ch);
}
fos.close();
fis.close();
}
BufferedOutputStream介紹
一、構(gòu)造方法:
1、BufferedOutputStream(OutputStream out);
創(chuàng)建一個(gè)帶有默認(rèn)長(zhǎng)度緩沖區(qū)的,字節(jié)輸出流。
2、BufferedOutputStream(OutputStream out,int sz);
創(chuàng)建一個(gè)指定長(zhǎng)度緩沖區(qū)的字節(jié)輸出流。
throws IllegalArgumentException when sz < 0 ;
BufferedInputStream介紹
一、構(gòu)造方法
BufferedInputStream(InputStream in);
創(chuàng)建一個(gè)默認(rèn)緩沖區(qū)大小的字節(jié)輸入流。
BufferedInputStream(ImputStream in,int sz);
創(chuàng)建一個(gè)指定緩沖區(qū)大小的字節(jié)輸入流。
二、其他方法
public int available();
返回不受阻塞地從此流讀取的字節(jié)數(shù)。
4、字節(jié)和字符流的相互轉(zhuǎn)換
獲取鍵盤輸入流 :
// 獲取鍵盤輸入流。字節(jié)流
InputStream in = System.in;
// 將字節(jié)流轉(zhuǎn)換成字符流對(duì)象。使用轉(zhuǎn)換流對(duì)象,InputStreamReader
InputStreamReader ins = new InputStreamReader(in);
// 加入緩沖區(qū)技術(shù)
BufferedReader r = new BufferedReader(ins);
// 綜上 ,獲取鍵盤輸入流的最常見寫法。
BufferedReader rr = new BufferedReader(new InputStreamReader(System.in));
InputStreamReader介紹
InputStreamReader 是字節(jié)流通向字符流的橋梁:他使用指定的charset(字符編碼)讀取字節(jié)并將其解碼為字符。
他使用的字符及可以顯示自定,否則使用系統(tǒng)默認(rèn)的字符集(JVM 環(huán)境)。
為了提高效率可以在BufferedReader中包裝一個(gè)InputStreamReader。例如:
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
一、構(gòu)造方法:
1、 InputStreamReader(InputStream in);
創(chuàng)建一個(gè)默認(rèn)字符集的InputStreamReader。
2、 InputStreamReader(InputStream in,Charset cs);
創(chuàng)建一個(gè)指定字符集的InputStreamReader。
3、 InputStreamReader(InputStream in,CharsetDecoder csd);
創(chuàng)建一個(gè)給定字符解碼器的InputStreamReader。
4、 InputStreamReader(InputStream in,String charsetName);
創(chuàng)建一個(gè)指定字符集的InputStreamReader。
二、其他方法
1、 public String getEncoding();
返回此流所使用的字符編碼名稱。
標(biāo)準(zhǔn)輸出流
// 獲取標(biāo)準(zhǔn)輸出流,字節(jié)流。
OutputStream out = System.out;
// 將字節(jié)流轉(zhuǎn)換成字符流。
OutputStreamWriter outs = new OutputStreamWriter(out);
// 加入緩沖區(qū)技術(shù)
BufferedWriter w = new BufferWriter(outs);
// 綜上,獲取標(biāo)準(zhǔn)輸出的最常見寫法:
BufferedWriter ww = new BufferedWriter(new OutputStreamWriter(System.out));
OutputStreamWriter介紹
OutputStreamWriter 是字符流通向字節(jié)流的橋梁。使用自定的charset將指定的字符編碼為字節(jié)。
字符集可以顯示指定也可以默認(rèn)。每次調(diào)用Write()都會(huì)針對(duì)給定的字符(字符集)調(diào)用編碼轉(zhuǎn)換器。
在寫入基礎(chǔ)流之前這些字節(jié)會(huì)在緩沖區(qū)中積累可以指定緩沖區(qū)大小。為了提高效率可以將
OutputStreamWriter封裝到BufferedWriter中,例如:
Writer out = new BufferedWriter(new OutputStreamWriter(System.out));
一、構(gòu)造方法
1、 OutputStreamWriter(OutputStream out);
創(chuàng)建一個(gè)默認(rèn)字符集的OutputStreamReader。
2、 OutputStreamWriter(OutputStream out,Charset cs);
創(chuàng)建一個(gè)指定字符集的OutputStreamReader。
3、 OutputStreamWriter(OutputStream out,CharsetDecoder csd);
創(chuàng)建一個(gè)給定字符解碼器的OutputStreamReader。
4、 OutputStreamWriter(OutputStream out,String charsetName);
創(chuàng)建一個(gè)指定字符集的OutputStreamReader。
二、其他方法
1、 public void flush();
刷新該流的緩沖。
2、 public String getEncoding();
獲取該流使用的字符編碼名
五、流操作的基本規(guī)律
通過三個(gè)明確來完成:
1、 明確源和目的
源:輸入流 ,InputStream、Reader。
目的:輸出流,OutputStream、Writer。
2、操作數(shù)據(jù)是否是純文本
是:字符流
否:字節(jié)流
3、明確體系后在明確所需要使用的對(duì)象。
通過設(shè)備來區(qū)分:
源設(shè)備:內(nèi)存、硬盤、鍵盤。
目的設(shè)備:內(nèi)存、硬盤、控制臺(tái)。
擴(kuò)展:把錄入的數(shù)據(jù)按照指定的編碼表utf-8,將數(shù)據(jù)保存到文件中。
分析:
1、 目的:OutputStream、Writer
2、 文本:Writer
3、 硬盤:FileWriter
4、 指定編碼,因此使用轉(zhuǎn)換流。
BufferedWriter w =
new BufferedWriter(new OutputStreamWriter(new FileOutputStream("1.txt"),"utf-8));
注意:通常在需要進(jìn)行編碼轉(zhuǎn)換時(shí)使用轉(zhuǎn)換流。字符通向字節(jié)。