天天看點

最全的IO操作知識總結

模拟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];

………………

繼續閱讀