模拟bufferedinputstream,編寫一個類
package toto.io;
import java.io.ioexception;
import java.io.inputstream;
private inputstream
in;
privatebyte[]
buf = newbyte[1024*4];
privateintpos = 0,count
= 0;
mybufferedinputstream(inputstream in){
this.in = in;
}
//從緩沖區中讀取一個位元組
/**
*緩沖區的原理:
*其實就是定義了一個臨時容器
*然後将擷取到的資料都存入到臨時容器中,通過臨時容器的方法擷取資料,當臨時容器
*中的資料取完後,再擷取一批資料進容器、
發現自定義的緩沖區出現了秒殺效果
為什麼秒殺呢?
因為mp3這樣的媒體資料,對應的二進制資料,很有可能出現連續多個1的情況。而連續的過程中,出現-1,程式就認為讀到了末尾,程式停止讀取。
為了避免這種情況,将擷取的一個位元組資料,進行提升,變成int ,并在保留原有八位的基礎上補零。補完後,就變成了正數,就避免了-1的這種情況。
*/
publicint myread()
throws ioexception{
if(count == 0){
count =
in.read(buf);//通過流對象從硬碟擷取一批資料裝入緩沖去
pos = 0;//從0開始取
byte b =
buf[pos];//将資料存入數組
pos++;//取完之後pos++
count--;//取走一個減少一個
returnb&oxff;
//這裡與上的是255。這裡進行了自動提升效果。
}elseif(count>0){
//第二次取時count>0
buf[pos];
pos++;
count--;
return b;
}else {
return -1;
}
publicvoid myclose()throws
ioexception{
in.close();
}
publicclass demo1 {
/*package toto.io;
import java.io.reader;
*//**
*按照裝飾設計模式的思想
*自定義mybufferedreader類
*一樣提供一個和bufferedreader功能相同的readline方法。
*//*
class mybufferedreader{//extends reader{
由于它裡面中提供reader中的所有方法,故它要繼承reader類。這裡繼承的原因是裡面的方法太多這裡不寫了
private filereader r;這種方式隻能包裝filereader類,
要想包裝所有的reader的子類,我們寫成以下方式:
private reader r;
mybufferedreader(reader r) {//這裡是被包對象
this.r = r;
提供一個一次讀一行的方法。
* 1、使用的還是reader中read()方法,一次讀一個。
* 2、将讀到一個字元進行臨時存儲。數組和stringbuilder都可以。
*
這裡選用stringbuilder,因為可以省略數組延長部分代碼的編寫。該builder中使用就是數組
而且可變長度,并且最終變成字元串。
* 3、因為自負有很多需要循環讀取。
* 4,讀取到的字元進行判斷,如果是回車符,那麼就将stringbuilder中的存儲資料作為字元串傳回
public string myreadline() throws ioexception {
stringbuilder sb = new stringbuilder();
int ch = 0;
while((ch==r.read())!=-1) {//使用初進來的read方法,并且要判斷不等于-1
if(ch=='\r')//遇到這個轉義字元時,不能将這個資料讀進去,并且将這個資料向下讀一個
continue;
if(ch=='\n')
return sb.tostring();
sb.append((char)ch);//如果兩個都滿足,就将資料向裡面轉了。
return null;
public void myclose() throws ioexception{
r.close();
public class mybufferedreader{
public static void main(string[] args) {
// todo auto-generated method stub
*/
轉換流
/*
*
轉換流,涉及的對象都在字元流體系中。
* inputstreamreader位元組轉到字元的橋梁。把看不懂得轉換成為看的懂的。
* outputstreamwriter:字元轉到位元組的橋梁。把看得懂的轉換成為看不懂的。
該類本身是一個字元流,因為它是橋梁,需要把一個指定的位元組流傳給構造函數。
将制定的位元組流轉成字元流。*/
import java.io.bufferedreader;
import java.io.inputstreamreader;
publicclass demo2 {
publicstaticvoid main(string[] args)throws
ioexception {
//readin();
// system.out.println('-'+0);
// system.out.println('1'+0);
readlinebykey();
/*
讀取鍵盤錄入,并打入的錄入的資料
當錄入了一行資料後,列印錄入的一行資料内容。而其可以不斷的進行錄入
一次列印一行。
*1,讀取鍵盤通過system.in完成
*2,需要一次列印一行。那麼就需要定義一個臨時容器,将讀取到自己額進行臨時存儲。
*當讀到回車符的時候就降臨時容器中存儲的資料一次性列印、*/
publicstaticvoid printlinebykey()
throws exception{
inputstream in = system.in;
int by = 0;
stringbuilder sb =
new stringbuilder();
while((by==in.read())!=-1){//這裡有警告,不知道為什麼
if(by=='\r')
if(by=='\n')
system.out.println(sb.tostring());
else
sb.append((char)by);
publicstaticvoid readin()
throws ioexception {
//擷取标準的輸入流,對應的預設裝置就是鍵盤。
//從鍵盤擷取到的資料都是位元組資料。
//讀取鍵盤錄入的一個位元組
//通過循環形式,讀取一個位元組,列印一個位元組
while((by=in.read())!=-1){
system.out.println(by);
publicstaticvoid readlinebykey()
//位元組讀取流
inputstream in =system.in;
//要想使用readline方法讀取一樣,就要建立bufferreader對象
//但是該字元流的緩沖區,在對象在初始化時,
//要将一個字元對象作為參數傳遞給bufferreader的構造函數
//讀取鍵盤是位元組流,如何讓字元流的緩沖區所使用呢?,這時就需要将位元組流轉成位元組流
//想要進行位元組和字元流的轉換,就需要io包中的轉換流
//由于早期隻有位元組流,隻有涉及到字元流之後才涉及到轉換,故這個轉換體系在字元流中。
//inputstreamreader的前面是位元組流,後面是字元流。故通過它轉換。
inputstreamreader isr =
new inputstreamreader(in);
//因為bufferedreader隻能包裝字元流。故隻需将isr傳遞進去就行了。
bufferedreader bufr =
newbufferedreader(isr);
string line = null;
while((line=bufr.readline())!=null){
if(line.equals("over")){
break;
}
//system.out.println(line.touppercase());
}
bufr.close();
/*流操作的基本規律
流操作要明确資料源和資料目的(資料彙)
在現有程式中,
源:鍵盤
目的控制台。
* 1、需求:将一個硬碟上的檔案列印在控制台上
* 2、需求:将鍵盤錄入的資料存儲到一個檔案中。
* */
import java.io.bufferedwriter;
import java.io.fileinputstream;
import java.io.fileoutputstream;
import java.io.outputstreamwriter;
publicclass transstreamdemo2 {
publicstaticvoid main(string[] args)
/*inputstream in = system.in;
inputstreamreader isr = new inputstreamreader(in);
bufferedreader bufr = new bufferedreader(isr);*/
//上面三行可以轉換成一行,讀取鍵盤最友善方式,因為鍵盤錄入的都是文本資料。是以一次讀一行最友善,先将位元組流包裝成字元流,再将字元流寫入緩沖區,提高效率。
/*bufferedreader bufr = new
bufferedreader(new inputstreamreader(system.in));*/
//硬碟上的檔案是位元組流,要将它轉換成字元流,讀取硬碟上的一個檔案的方式:
bufferedreader bufr =
new
bufferedreader(new inputstreamreader(new
fileinputstream("檔案位址")));
/*向控制台上輸出,使用system.out
outputstream out = system.out;
outputstreamwriter osw = new outputstreamwriter(out);
bufferedwriter bufw = new bufferedwriter(osw);*/
// bufferedwriter bufw = new bufferedwriter(new outputstreamwriter(system.out));
//寫需求1時,上面包裝流中式檔案路徑,下面是system.out,當寫需求2時,上面是system.in,下面是要寫到的檔案的路徑。當上下都是檔案名稱時,相當于檔案的複制。
bufferedwriter bufw =
new bufferedwriter(new outputstreamwriter(new
fileoutputstream("要寫到的檔案的位址")));
string line = null;
while((line==bufr.readline())!=null){
if("over".equals(line)){
break;
}
bufw.write(line.touppercase());
bufw.newline();
bufw.flush();
bufw.close();
bufr.close();
io包中對象其實都是以圍繞讀寫為主,用于操作資料。
io技術的難點:因為io包中的對象太多,在實際開發,不太容易明确使用哪個對象
io操作的基本規律:
1、 作用的資料源和資料目的。
如果是操作資料源:輸入流。(inputstream
,reader),讀入的是位元組流用inputstream,讀入的是字元流用reader.
如果是操作資料彙:就是輸入流。(outputstream,writer),輸出成位元組流用outputstream,輸出成字元用writer
2、 要操作的資料是不是純文字資料。
如果是:使用字元流
如果不是:使用位元組流。
3,根據源和目的的裝置來确定要操作的對象。
無論資料源或者資料彙都有存在裝置。
源裝置:硬碟(file)。鍵盤(鍵盤對應的是system.in)。記憶體(記憶體對應的都是數組)。
目的裝置:硬碟(file),控制台(控制台對應的是:system.out),記憶體(記憶體對應的是數組)。
這兩個明确可以确定到底要使用上面四個體系中的那個體系。
需求一:對文本檔案進行複制
1, 這個需求既有源又有目的
源:硬碟上的檔案。inputstream reader
目的:硬碟上的檔案。outputstream or writer
是不是純文字資料呢?是。
源:要使用字元讀取流reader
目的:要使用字元輸出流writer
那麼體系确定後,要使用該體系中那個對象呢?
源:是一個檔案。是以要使用字元讀取流中可以操作檔案的對象:filereader
目的:也是一個檔案,是以要使用字元寫入流中的可以操作檔案的對象:filewriter
filereader fr = new filereader(“a.txt”);
filewriter fw = new filewriter(“b.txt”);
該操作過程中是否需要提高俠侶呢?是。
如果是:加入緩沖技術。
代碼就變成:
bufferedreader bufr = new bufferedreader(newfilereader(“a.txt”));
bufferedwriter bufw = newbufferedwriter(new filewriter(“b.txt”));
需求二,将一個硬碟上的檔案列印在控制台上。
1, 明确源和目的
源:硬碟的檔案。讀取檔案,體系是inputstream or reader
目的:控制台。outputstream or writer
對于控制台較為特殊,其預設的目的是system.out
2, 是不是純文字資料
是
源:reader
目的writer
3,明确體系中的對象
源:因為是一個檔案,filereader
目的:因為是控制台對應的對象是system.out,為了便于字元操作,是以将system.out轉換成字元流。
filereader fr =new filereader(“a.txt”);
讀取字元流
outputstreamwriterout =new outputstreamwriter(system.out;); //輸出位元組流
outputstreamwriterosw = new outputstreamwriter(system.out);這裡也變成了字元流了。
char[] buf = new char[1024];
int len = 0;
while((len=fr.read(buf))!=-1){
osw.writer(buf,o.len); //将資料寫到目的了(buf),即控制體。
為了提高效率,加入緩沖技術。
bufferedreader buf = new bufferreader(newfilereader(“a.txt”));
bufferedwriter bufw = newbufferedwriter(new outputstreamwriter(“b.txt”));
string line = null;
while((lien=bufr.readline())!=null){
bufw.write(line);
bufw.newline();
bufw.flush();
需求三,将錄入的檔案寫入硬碟上的檔案。
1,明确體系;
源:inputstream。 system.in
目的:硬碟檔案 outputstream,writer。
2, 明确純文字。
因為鍵盤錄入的都是位元組資料。但是該資料最終得轉化成為純文字。
是以可以使用字元流。
目的:writer。
3, 明确體系對象
源:因為鍵盤錄入,對應的對象是system.in,是一個位元組讀取流。
為了可以使用字元讀取留來操作這些資料,可以将其轉換成字元讀取流
目的:因為是一個文本檔案,是以可以使用filewriter。
inputstreamreaderisr = new inputstreamreader(system.in);
filewriter fw =new filewriter(“a.txt”);
為了提高效率,加入了緩沖技術
bufferreader bufr = new bufferedreader(newinputstreamreader(system,in));
bufferedwriter bufw = newbufferedwriter(new filewriter(“a.txt”));
需求四:讀取鍵盤錄入,将錄入的資訊列印在控制台上,
1體系:
源:inputstream reader
目的:outputstream,writer
2純文字:是
目的:writer
4, 對象:
源:system.in
目的:system.out
因為鍵盤錄入都是純文字,是以用字元流操作很友善。
那麼就将源和目的都轉換成字元流
inputstreamreader isr = newinputstreamreader(system.in);
outputstreamwriter osw = newoutputstreamwriter(system.out);
需要高效
bufferedreader bufr = newbufferedreader(new inputstreamreaderl(system,in));
bufferedwriter bufw = newbufferedwriter(new outputstreamwriter(system.out));
注意:在使用寫入緩沖區時,記得要進行重新整理。flush().
需求五:将一個文本檔案中的資料存儲到另一個文本檔案中,要求按照utf-8的編碼形式存儲
1, 體系
源inputstream or reader
目的:outputstream or writer
2,純文字?yes
3,對象:
因為操作是文本,而且沒有指定編碼。是以可以按照預設編碼形式
。那麼就可以使用filereader
目的:
按照一般思想,會去找filewriter。但是filewriter使用的預設編碼。
而需求中要求按照指定編碼utf-8形式存儲
那麼這時就要用到轉換流,因為隻有轉換流可以在初始化是指定編碼。
目的也是一個檔案。那麼就明确要使用的對象是fileoutstream。
filereader fr =new filereader(“a.txt”);
outlputstreamwriterosw = new outputstream(new fileoutputstream(“b.txt”),”utf-8”);
需要提高效率
bufferedreaderbufr = new bufferedreader(new filereader(a.txt));
bufferedwriter bufw = new bufferedwriter(new outputstreamwriter(newfileoutputstream(“b.txt”),”utf-8”));
import java.io.filereader;
import java.io.filewriter;
public class transstreamdemo {
/**
* @param args
*/
publicstatic void main(string[] args)throws ioexception {
//writetext();
readtext();
publicstatic void readandwrite()throws ioexception{
filereaderfr = new filereader("test.txt");//字元流
//filewriterfw = new filewriter("test1.txt");//預設的字元集。
outputstreamwriterosw = new outputstreamwriter(new
fileoutputstream("text1.txt"),"utf-8");//字元流
char[] buf = new char[1024];
intlen = 0;
while((len=fr.read(buf))!=-1){
osw.write(buf,0,len);
}
osw.close();
fr.close();
publicstatic void readtext() throws ioexception{
filereaderfr = new filereader("test.txt");//這種編碼預設是gbk
intch = fr.read();
system.out.println((char)ch);
intch1 = fr.read();
system.out.println((char)ch1);
publicstatic void writetext() throws ioexception{
filewriterfw = new filewriter("test.txt");
fw.write("你好");
fw.close();
讀取一個utf-8編碼的檔案。
bufferedreader bufr =
)
或通過:
inputstreamreaderisr = new inputstreamreader(new fileinputstream(“text.txt”,”utf-8”));
char[] buf = new char[1024];
………………