InputStreamReader和BufferedReader用法及實(shí)例講解
一、BufferedReader類
. 所屬類庫(kù):
java.lang.Object
java.io.Reader
java.io.BufferedReader
. 基本概念 :
public class BufferedReader extends Reader
從字符輸入流中讀取文本,緩沖各個(gè)字符,從而實(shí)現(xiàn)字符、數(shù)組和行的高效讀取。 可以指定緩沖區(qū)的大小,或者可使用默認(rèn)的大小。大多數(shù)情況下,默認(rèn)值足夠大。
通常, Reader 所作的每個(gè)讀取請(qǐng)求都會(huì)導(dǎo)致對(duì)底層字符或字節(jié)流進(jìn)行相應(yīng)的讀取請(qǐng)求。因此,建議用 BufferedReader 包裝所有其 read() 操作可能開(kāi)銷很高的 Reader (如 FileReader 和 InputStreamReader )。
BufferedReader 流能夠讀取文本行 , 通過(guò)向 BufferedReader 傳遞一個(gè) Reader 對(duì)象 , 來(lái)創(chuàng)建一個(gè) BufferedReader 對(duì)象 , 之所以這樣做是因?yàn)?FileReader 沒(méi)有提供讀取文本行的功能 .
. Demo :
通過(guò) Bufferedreader 捕獲所輸入的語(yǔ)句 :
import java.io.*;
class BufferedReaderDemo{
public static void main(String[] args)throws IOException {
BufferedReader bufferedReader =new BufferedReader(
new InputStreamReader(System.in));
System.out.print("請(qǐng)輸入一系列文字,可包括空格:");
String text =bufferedReader.readLine();
System.out.println("請(qǐng)輸入文字:"+text);
}
}
注解:
throws IOException 拋出異常
InputStreamReader 是字節(jié)流通向字符流的橋梁
二、InputStreamReader類
InputStreamReader 將字節(jié)流轉(zhuǎn)換為字符流。是字節(jié)流通向字符流的橋梁。如果不指定字符集編碼,該解碼過(guò)程將使用平臺(tái)默認(rèn)的字符編碼,如:GBK。
構(gòu)造方法 :
InputStreamReader isr = new InputStreamReader(InputStream in);//構(gòu)造一個(gè)默認(rèn)編碼集的InputStreamReader類
InputStreamReader isr = new InputStreamReader(InputStream in,String charsetName);//構(gòu)造一個(gè)指定編碼集的
InputStreamReader類。
參數(shù) in對(duì)象通過(guò) InputStream in = System.in;獲得。//讀取鍵盤(pán)上的數(shù)據(jù)。
或者 InputStream in = new FileInputStream(String fileName);//讀取文件中的數(shù)據(jù)??梢钥闯?FileInputStream 為InputStream的子類。
主要方法 :int read();//讀取單個(gè)字符。
int read(char []cbuf);//將讀取到的字符存到數(shù)組中。返回讀取的字符數(shù)。
. Demo :
import java.io.*;
class InputStreamReaderDemo {
public static void transReadNoBuf() throws IOException {
/**
* 沒(méi)有緩沖區(qū),只能使用read()方法。
*/
//讀取字節(jié)流
//InputStream in = System.in;//讀取鍵盤(pán)的輸入。
InputStream in = new FileInputStream("D:\\demo.txt");//讀取文件的數(shù)據(jù)。
//將字節(jié)流向字符流的轉(zhuǎn)換。要啟用從字節(jié)到字符的有效轉(zhuǎn)換,
//可以提前從底層流讀取更多的字節(jié).
InputStreamReader isr = new InputStreamReader(in);//讀取
//綜合到一句。
//InputStreamReader isr = new InputStreamReader(
//new FileInputStream("D:\\demo.txt"));
char []cha = new char[1024];
int len = isr.read(cha);
System.out.println(new String(cha,0,len));
isr.close();
}
public static void transReadByBuf() throws IOException {
/**
* 使用緩沖區(qū) 可以使用緩沖區(qū)對(duì)象的 read() 和 readLine()方法。
*/
//讀取字節(jié)流
//InputStream in = System.in;//讀取鍵盤(pán)上的數(shù)據(jù)
InputStream in = new FileInputStream("D:\\demo.txt");//讀取文件上的數(shù)據(jù)。
//將字節(jié)流向字符流的轉(zhuǎn)換。
InputStreamReader isr = new InputStreamReader(in);//讀取
//創(chuàng)建字符流緩沖區(qū)
BufferedReader bufr = new BufferedReader(isr);//緩沖
//BufferedReader bufr = new BufferedReader(
//new InputStreamReader(new FileInputStream("D:\\demo.txt")));可以綜合到一句。
/*int ch =0;
ch = bufr.read();
System.out.println((char)ch);
*/
String line;
while((line = bufr.readLine())!=null){
System.out.println(line);
}
isr.close();
}
}
三、InputStreamReader、BufferedReader真實(shí)案例(非編碼集)
import java.io.*;
class UtilResource {
private void initializeResource() {
try {
//讀取文件,并且以u(píng)tf-8的形式寫(xiě)出去
BufferedReader bufread;
String read;
bufread = new BufferedReader(new InputStreamReader(ResourceHelper
.getResourceInputStream("pinyin.txt")));
while ((read = bufread.readLine()) != null) {
System.out.println(read);
}
bufread.close();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
注:其中 pinyin.txt 放于項(xiàng)目的根目錄下
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
class ResourceHelper {
/**
* @param resourceName
* @return
* @return
*/
static BufferedInputStream getResourceInputStream(String resourceName) {
try {
return new BufferedInputStream(new FileInputStream(resourceName));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
總結(jié):
InputStreamReader 類
是字節(jié)流通向字符流的橋梁,封裝了InputStream在里頭, 它以較高級(jí)的方式,一次讀取一個(gè)一個(gè)字符,以文本格式輸入 / 輸出,可以指定編碼格式;
BufferedReader 類
BufferedReader 由Reader類擴(kuò)展而來(lái),提供通用的緩沖方式文本讀取,而且提供了很實(shí)用的readLine,讀取一個(gè)文本行,從字符輸入流中讀取文本,緩沖各個(gè)字符,從而提供字符、數(shù)組和行的高效讀取。
ps:InputStream、InputStreamReader和Reader的關(guān)系
InputStream:得到的是字節(jié)輸入流,InputStream.read("filename")之后,得到字節(jié)流
Reader:讀取的是字符流
InputStreamReader:從字節(jié)到字符的橋梁。InputStreamReader(InputStream.read("filename"));
reader.read(InputStreamReader(InputStream in));便可從字節(jié)變?yōu)樽址?,打印顯示了。
java.io.Reader 和 java.io.InputStream 組成了Java 輸入類。
Reader 用于讀入16位字符,也就是Unicode 編碼的字符;而 InputStream 用于讀入 ASCII 字符和二進(jìn)制數(shù)據(jù)。
Reader支持16位的Unicode字符輸出,InputStream支持8位的字符輸出。
Reader和InputStream分別是I/O庫(kù)提供的兩套平行獨(dú)立的等級(jí)機(jī)構(gòu),1byte = 8bits InputStream、OutputStream是用來(lái)處理8位元的流,Reader、Writer是用來(lái)處理16位元的流。
而在JAVA語(yǔ)言中,byte類型是8位的,char類型是16位的,所以在處理中文的時(shí)候需要用Reader和Writer。
值得說(shuō)明的是,在這兩種等級(jí)機(jī)構(gòu)下,還有一道橋梁InputStreamReader、OutputStreamWriter負(fù)責(zé)進(jìn)行InputStream到Reader的適配和由OutputStream到Writer的適配。
在 Java中,有不同類型的 Reader 輸入流對(duì)應(yīng)于不同的數(shù)據(jù)源:
FileReader 用于從文件輸入; CharArrayReader 用于從程序中的字符數(shù)組輸入; StringReader 用于從程序中的字符串輸入; PipedReader 用于讀取從另一個(gè)線程中的 PipedWriter 寫(xiě)入管道的數(shù)據(jù)。
相應(yīng)的也有不同類型的 InputStream 輸入流對(duì)應(yīng)于不同的數(shù)據(jù)源:FileInputStream,ByteArrayInputStream,StringBufferInputStream,PipedInputStream。
另外,還有兩種沒(méi)有對(duì)應(yīng) Reader 類型的 InputStream 輸入流: Socket 用于套接字; URLConnection 用于 URL 連接。 這兩個(gè)類使用 getInputStream() 來(lái)讀取數(shù)據(jù)。
相應(yīng)的,java.io.Writer 和 java.io.OutputStream 也有類似的區(qū)別。
關(guān)于InputStream.read(byte[] b)和InputStream.read(byte[] b,int off,int len)這兩個(gè)方法都是用來(lái)從流里讀取多個(gè)字節(jié)的,有經(jīng)驗(yàn)的程序員就會(huì)發(fā)現(xiàn),這兩個(gè)方法經(jīng)常 讀取不到自己想要讀取的個(gè)數(shù)的字節(jié)。比如第一個(gè)方法,程序員往往希望程序能讀取到b.length個(gè)字節(jié),而實(shí)際情況是,系統(tǒng)往往讀取不了這么多。仔細(xì)閱讀Java的API說(shuō)明就發(fā)現(xiàn)了,這個(gè)方法 并不保證能讀取這么多個(gè)字節(jié),它只能保證最多讀取這么多個(gè)字節(jié)(最少1個(gè))。因此,如果要讓程序讀取count個(gè)字節(jié),最好用以下代碼:
byte[] b = new byte[count];
int readCount = 0; // 已經(jīng)成功讀取的字節(jié)的個(gè)數(shù)
while (readCount < count) {
readCount += in.read(bytes, readCount, count - readCount);
}
用這段代碼可以保證讀取count個(gè)字節(jié),除非中途遇到IO異?;蛘叩搅藬?shù)據(jù)流的結(jié)尾(EOFException)
相關(guān)文章
java中SynchronizedList和Vector的區(qū)別詳解
這篇文章主要介紹了java中SynchronizedList和Vector的區(qū)別詳解,Vector是java.util包中的一個(gè)類。 SynchronizedList是java.util.Collections中的一個(gè)靜態(tài)內(nèi)部類。,需要的朋友可以參考下2019-06-06
解讀List?list=new?ArrayList()是怎么回事
這篇文章主要介紹了解讀List?list=new?ArrayList()是怎么回事,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
MapReduce實(shí)現(xiàn)TopN效果示例解析
這篇文章主要為大家介紹了MapReduce實(shí)現(xiàn)TopN效果示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
必知必會(huì)的SpringBoot實(shí)現(xiàn)熱部署兩種方式
這篇文章主要為大家介紹了必知必會(huì)的SpringBoot實(shí)現(xiàn)熱部署兩種方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
關(guān)于RedisTemplate之opsForValue的使用說(shuō)明
這篇文章主要介紹了關(guān)于RedisTemplate之opsForValue的使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
Springboot 中使用 Aop代碼實(shí)戰(zhàn)教程
AOP的編程思想是把對(duì)類對(duì)象的橫切問(wèn)題點(diǎn),從業(yè)務(wù)邏輯中分離出來(lái),從而達(dá)到解耦的目的,增加代碼的復(fù)用性,提高開(kāi)發(fā)效率,這篇文章主要介紹了Springboot中使用Aop代碼實(shí)戰(zhàn)教程,需要的朋友可以參考下2023-07-07
Java 關(guān)于時(shí)間復(fù)雜度和空間復(fù)雜度的深度刨析
算法復(fù)雜度分為時(shí)間復(fù)雜度和空間復(fù)雜度。其作用: 時(shí)間復(fù)雜度是度量算法執(zhí)行的時(shí)間長(zhǎng)短;而空間復(fù)雜度是度量算法所需存儲(chǔ)空間的大小2021-11-11

