JavaIO流03
4.常用的類02
4.4節點流和處理流


4.4.1基本介紹
-
節點流可以從一個特定的資料源讀寫資料,如FileReader、FileWriter
資料源就是存放資料的地方,比如檔案、陣列、字串、管道等

- 處理流(也叫包裝流)是“連接”在已經存在的流(節點流或者處理流)之上,為程式提供更為強大的讀寫功能,也更加靈活,如BufferedReader、BufferedWriter

- 節點流和處理流的區別和聯系:
- 節點流是底層流(低級流),直接和資料源相連接,
- 處理流(包裝流)對節點流進行了包裝,既可以消除不同節點流的實作差異,也可以提供更方便的方法來完成輸入輸出,
- 處理流對節點流進行了包裝,使用了修飾器的設計模式,不會直接與資料源相連接,

-
處理流特點:
1.性能的提高:主要以增加緩沖的方式來提高輸入輸出的效率,
2.操作的便捷:處理流提供了一系列便捷的方法來一次輸入輸出大批量的資料,使用更加靈活方便,
4.4.2模擬包裝流-修飾器模式
Reader_:
package li.io;
/**
* 模擬包裝流的修飾器模式
*/
public abstract class Reader_ {//抽象類
public void readFile() {}
public void readString() {}
}
FileReader_:
package li.io;
public class FileReader_ extends Reader_ {//模擬節點流
public void readFile() {
System.out.println("對檔案進行讀取...");
}
}
StringReader_:
package li.io;
public class StringReader_ extends Reader_ {//模擬節點流
public void readString() {
System.out.println("讀取字串...");
}
}
BufferedReader_:
package li.io;
/**
* 模擬處理流(包裝流)
*/
public class BufferedReader_ extends Reader_ {
private Reader_ reader_;//屬性是Reader_型別
public BufferedReader_(Reader_ reader_) {
this.reader_ = reader_;
}
public void readFile(){//封裝一層
reader_.readFile();
}
//讓方法更加靈活,比如多次讀取檔案,或者加緩沖byte[]...
public void readFile(int num) {
for (int i = 0; i < num; i++) {
reader_.readFile();
}
}
//又如擴展readString方法,例如批量處理字串資料...
public void readString(int num) {
for (int i = 0; i < num; i++) {
reader_.readString();
}
}
}
Test_:
package li.io;
public class Test_ {
public static void main(String[] args) {
BufferedReader_ bufferedReader_ = new BufferedReader_(new FileReader_());
bufferedReader_.readFile(3);
bufferedReader_.readFile();
BufferedReader_ bufferedReader02_ = new BufferedReader_(new StringReader_());
bufferedReader02_.readString(2);
}
}
4.4.3字符處理流-BufferedReader&BufferedWriter
-
BufferedReader和BufferedWriter屬于字符流,是按照字符來讀取資料的
-
在關閉流時,只需要關閉外層流(即包裝流)即可
- BufferedReader構造方法:
BufferedReader常用方法:
public int read() throws IOException
//讀取單個字符,
//作為一個整數(其范圍從 0 到 65535 (0x00-0xffff))讀入的字符,如果已到達流末尾,則回傳 -1
public int read(char[] cbuf) throws IOException
//一次讀取一個位元組陣列
//cbuf - 目標緩沖區
//讀取的字符數,如果已到達流的末尾,則回傳 -1
public void close() throws IOException
//關閉該流并釋放與之關聯的所有資源,
public String readLine() throws IOException
//讀取一個文本行,通過下列字符之一即可認為某行已終止:換行 (’\n’)、回車 (’\r’) 或回車后直接跟著換行,
//包含該行內容的字串,不包含任何行終止符,如果已到達流末尾,則回傳 nu
- BufferedWriter構造方法:
BufferedWriter常用方法:
void write(char ch);//寫入單個字符,
void write(char []cbuf,int off,int len)//寫入字符資料的某一部分,
void write(String s,int off,int len)//寫入字串的某一部分,
void newLine()//寫入一個行分隔符,
void flush();//重繪該流中的緩沖,將緩沖資料寫到目的檔案中去,
void close();//關閉此流,在關閉前會先重繪
應用案例1:使用BufferedReader讀取文本檔案,并顯示在控制臺
package li.io.reader_;
import java.io.BufferedReader;
import java.io.FileReader;
//演示BufferedReader的使用
public class BufferedReader_ {
public static void main(String[] args) throws Exception {
String filePath = "d:\\note.txt";
//創建
BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
//讀取
String line;
//readLine():按行讀取檔案,當回傳null時,表示檔案讀取完畢
while((line = bufferedReader.readLine())!=null){
System.out.println(line);
}
//關閉流:這里只需要關閉BufferedReader,底層會去自動地關閉節點流
bufferedReader.close();
}
}
思考:為什么只需要關閉外層流?
在代碼bufferedReader.close();處打上斷點,點擊force step into,可以看到下圖所示:
在底層呼叫的其實是:傳進去的節點流物件的close()方法
這里的in就是我們傳入的new FileReader(filePath)
應用案例2:使用BufferedWriter將“一只可愛的小貓咪”寫入到檔案中
package li.io.writer_;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
//演示BufferedWriter的使用
public class BufferedWriter_ {
public static void main(String[] args) throws IOException {
String filePath = "d:\\ok.txt";
//創建BufferedWriter物件
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));
//寫入
bufferedWriter.write("一只可愛的小貓咪");
bufferedWriter.newLine();//插入一個和系統相關的換行
bufferedWriter.write("兩只可愛的小貓咪");
bufferedWriter.newLine();
bufferedWriter.write("三只可愛的小貓咪");
bufferedWriter.newLine();
//關閉外層流即可,底層自動關閉穿入的內層流
bufferedWriter.close();
}
}
案例3:綜合使用 BufferedReader & BufferedWriter 完成檔案文本拷貝,注意檔案編碼,
package li.io.writer_;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
public class BufferedCopy_ {
public static void main(String[] args) throws Exception {
//注意:BufferedReader 和 BufferedWriter都是字符流操作
// 不要去操作二進制檔案[聲音,視頻,doc,pdf等],可能造成檔案損壞
String srcFilePath = "d:\\note.txt";//源檔案
String destFilePath = "d:\\note2.txt";
String line = null;
//創建BufferedReader&BufferedWriter物件
BufferedReader bufferedReader = new BufferedReader(new FileReader(srcFilePath));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(destFilePath));
//讀入和寫出
while ((line = bufferedReader.readLine()) != null) {//每讀取一行內容就寫入
bufferedWriter.write(line);
bufferedWriter.newLine();//換行
}
System.out.println("拷貝完畢~");
//關閉兩個外層流
bufferedReader.close();
bufferedWriter.close();
}
}
4.4.4位元組處理流-BufferedInputStream&BufferedOutputStream
-
BufferedInputStream
BufferedInputStream是位元組流,在創建BufferedInputStream時會創建一個內部緩沖區陣列,
常用方法:
int available()
//用于回傳輸入流中可用的未讀位元組數,而不會由于下一次為此InputStream的方法的呼叫而阻塞,
void close()
//關閉此輸入流并釋放與該流關聯的所有系統資源,
void mark(int readlimit)
//輸入流的當前位置做個標記,readlimit引數是輸入流在標記位置失效前允許讀取的位元組數,
boolean markSupported()
//測驗輸入流是否支持mark和reset方法,
int read()
//讀取一個位元組,
int read(byte[] b, int off, int len)
//讀取多個位元組到位元組陣列b中,引數off是陣列偏移量,引數len是讀取資料的長度,
void reset()
//重置流的當前位置到前面標記的位置,
long skip(long n)
//略過流中的資料,若資料不夠時,跳過僅有的位元組,回傳跳過的位元組數,
-
BufferedOutputStream
BufferedOutputStream是位元組流,實作緩沖的輸出流,可以將多個位元組寫入底層的輸出流中,而不必對每次位元組寫入呼叫底層系統
應用案例:
要求:編程完成圖片/音樂的拷貝(要求使用 BufferedInputStream 和 BufferedOutputStream 流)
package li.io.outputstream_;
import java.io.*;
/**
* 演示使用 BufferedInputStream 和 BufferedOutputStream
* 使用它們可以拷貝二進制檔案
* 同時也可以拷貝文本檔案
*/
public class BufferedCopy02 {
public static void main(String[] args) {
String srcFilePath = "d:\\蘭亭序 - 周杰倫.mp3";
String destFilePath = "d:\\ltx-zhou.mp3";
//創建BufferedInputStream 和 BufferedOutputStream物件
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream(srcFilePath));
bos = new BufferedOutputStream(new FileOutputStream(destFilePath));
//回圈寫入并讀取
byte[] buf = new byte[1024];
int readLen = 0;
//read(byte[]):當回傳-1時就表示檔案讀取完畢
while ((readLen = bis.read(buf)) != -1) {
bos.write(buf, 0, readLen);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//關閉外層流
try {
if (bos != null) {
bos.close();
}
if (bis != null) {
bis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

注意:位元組流可以操作二進制檔案,同時也可以操作文本檔案
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/506111.html
標籤:Java
上一篇:每日一考-9.11
下一篇:快取與資料庫結合使用的痛點
