1. 程式人生 > >Java第二十一天學習筆記~字元流緩衝區

Java第二十一天學習筆記~字元流緩衝區

字元流

Reader是字元輸入流的基類,用於從某個源裝置讀取字元

Writer是字元輸出流,用於向某個目標裝置寫入字元

字元流操作檔案

字元輸入流FileReader,通過此流可以從關聯的檔案中讀取一個或一組字元。

在程式開發中,經常需要向檔案中寫入字元,可以使用Writer的一個子類FileReader。

需求:在硬碟上,建立一個檔案,並寫入一些文字資料。

用於操作操作檔案的Writer的子類FileWriter,字尾名是父類名。字首名是該流物件的功能。



import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopyTextTest {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		
		FileReader fr=new FileReader("IO流_2.txt");
		
		FileWriter fw=new FileWriter("copytext_1.txt");
		
		int ch=0;
		while((ch=fr.read())!=-1) {
			fw.write(ch);
		}
		fw.close();
		fr.close();
		

	}

}
package cn.itcast.p1.io.charstream.test;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopyTextTest_2 {

	private static final int BUFFER_SIZE = 1024;

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		FileReader fr=null;
		FileWriter fw=null;
		try 
		{
			fr=new FileReader("IO流_2.txt");
			fw=new FileWriter("copytest_2.txt");
			//建立一個臨時容器,用於快取讀取到的字元
			char[] buf=new char[BUFFER_SIZE];//緩衝區
			
			int len=0;
			while((len=fr.read(buf))!=-1) {
				fw.write(buf, 0, len);
			}
			
			
		}catch (Exception e) {
			//System.out.println("讀寫失敗");
			throw new RuntimeException("讀寫失敗");
		}finally {
			if(fw!=null)
				try {
					fw.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			if(fr!=null)
				try {
					fr.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		  
	}

}

操作步驟:

    1.建立一個FileWriter物件。該物件一被初始化就必須明確要被操作的檔案,該檔案會被建立到指定目錄下,如果該目錄下已經有同名檔案,將被覆蓋

    FileWriter fw=new FileWriter("demo.txt");

    2.呼叫write方法,將字串寫入到流中。

    fw.write();

    3.重新整理流物件中的緩衝中的資料,將資料刷到目的地

    fw.flush();

    4.關閉流資源,但是關閉之前會重新整理一次內部的緩衝中的資料,將資料刷到目的地中。和flush的區別,flush重新整理後,流可以繼續使用,close重新整理後將會將流關閉。

    fw.close();

字元檔案輸入流FileReader

針對字元進行操作,而不是位元組。它的間接父類是字元流Reader。FileWriter是用於寫入字元檔案的便捷類。

在FileReader類中未自定義方法,而是繼承了其父類及間接父類中的方法。

構造方法

    public FileReader(File file)                 在給定從中讀取資料的File的情況下建立一個新類

    public FileReader(String fileName)    在給定從中讀取資料的檔名的情況下建立一個新類

 

字元檔案輸出流FileWriter

構造方法

    FileWriter(File file)                              通過file物件建立FileWriter

    FileWriter(File file, boolean append)  通過file物件建立類,append為true或false表示是否在檔案追加

    FileWriter(FileDescriptor fd)               引數fd為檔案描述符,通過檔案描述符建立FileWriter

    FileWriter(String fileName)                 引數fileName為檔案路徑名,通過檔案路徑建立FileWriter

    FileWriter(String fileName, boolean append) 

 

字元輸入流Reader

該類是抽象類,不能被例項化

方法

    abstract void close()             關閉輸入流

    void mark ()                           在輸入流中標記當前位置

    boolean markSupported ()    測試輸入流是否支援mark()和reset()方法

    int read ()                              從輸入流讀取下一字元

    int read (char[] cbuf)             從輸入流讀取若干字元資料,並存儲到字元陣列

    abstract int read (char[] cbuf, int off, int len)       從輸入流讀取至多len個字元資料,並存儲到字元陣列

    boolean void ready ()           判斷是否準備讀取輸入流

    void reset ()                          將輸入流重新定位到mark()方法標記的位置

    long skip (long n)                  跳過輸入流中n個字元資料

 

字元輸出流Writer

該類是抽象類,不能被例項化

方法

    abstract void close()                     關閉輸出流

    abstract void flush()                      重新整理輸出流,強制將緩衝區內容寫入輸出流

    void write(char[] cbuf)                   將指定字元陣列的內容寫入輸出流

    abstract void write(char[] cbuf,int off,int len)          將指定字元陣列從off位置開始的len個字元寫入輸出流

    write(int c)                                    將指定的字元寫入輸出流

    write(String str)                            將指定的字串寫入輸出流

    write(String str,int off,int len)        將指定字串從off位置開始的len個字元寫入輸出流

 

字元流的緩衝區

字元流提供了帶緩衝區的包裝流,分別是BufferedReader和BufferedWriter,其中BufferedReader用於對字元輸入流進行包裝,BufferedWriter用於對字元輸出流進行包裝。

緩衝區的出現提高了對資料的讀寫效率

對應類:BUfferWriter 、BufferedReader

特點:緩衝區要結合流才可以使用,在建立緩衝區之前,必須要有流物件。在流的基礎上對流的功能進行了增強。

 

BufferedWriter步驟

    1.建立一個字元寫入流物件

        FileWriter fw=new FileWriter("a.txt");

    2.將需要被提高效率的流物件作為引數傳遞給緩衝區的建構函式

        bufferedWriter bufw=new BufferedWriter(fw);

        buff.write("asdasdas");

        bufw.newLine();//換行符,跨平臺的

    3.將緩衝區重新整理

        bufw.flush;

    4.關閉緩衝區,就是在關閉緩衝區中的流物件

 

BufferedReader步驟

    1.建立一個字元寫入流物件

        FileReader fr=new FileReader ("a.txt");

    2.將需要被提高效率的流物件作為引數傳遞給緩衝區的建構函式

        BufferedReader bufr=new BufferedReader (fr);

    3.讀取流物件:該緩衝區提供了一個一次讀取一行的方法。當返回null時表示,檔案讀到末尾

        String line=null;

        while((line=bufr.readLine())!=null) {

        String s=line;}

    4.關閉

        bufr.close();

readLine()方法的原理:無論是讀一行,獲取多個字元,最終都是在硬碟上一個一個讀取,最終使用額還是read方法一次讀一個的方法。

 

通過緩衝區複製一個文字檔案



import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopyTextByBufTest {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		FileReader fr=new FileReader("buf.txt");
		BufferedReader bufr=new BufferedReader(fr);
		
		FileWriter fw=new FileWriter("buf_copy.txt");
		BufferedWriter bufw=new BufferedWriter(fw);
		
		String line=null;
		while((line=bufr.readLine())!=null) {
			bufw.write(line);
		}
		/*int ch=0;
		while((ch=bufr.read())!=-1) {
			bufw.write(ch);
		}
		*/
		bufw.close();
		bufr.close();
	}

}

 

字元緩衝區輸入流BufferedReader

從字元輸入流中讀取文字,緩衝各個字元,從而提供字元、陣列和行的高效讀取。

構造方法

    public BufferedReader(Reader in)                建立一個使用預設大小輸入緩衝區的輸入流

    public BufferedReader(Reader in, int size)   建立一個使用size指定大小輸入緩衝區的輸入流

方法

    void close()                                 關閉該流

    void mark(int readAheadLimit)    標記流中的當前位置

    boolean markSupported()           判斷此流是否支援mark()操作

    int read()                                     讀取單個字元

    int read(char[] cbuf, int off, int len)         將字元讀入陣列的某一部分

    String readLine()                         讀取一個文字行

    boolean ready()                          判斷此流是否已準備好被讀取

    void reset()                                 將流重置為最新的標記

    long skip(long n) 跳過字元

字元緩衝區輸出流BufferedWriter

將文字寫入字元輸出流,緩衝各個字元,從而提供單個字元、陣列和字串的高效寫入。可以指定緩衝區的大小,或者接受預設的大小。

構造方法

    public BufferedWriter(Writer out)                建立一個使用預設大小輸出緩衝區的輸出流

    public BufferedWriter(Writer out, int size)   建立一個使用size指定大小輸出緩衝區的輸出流

方法

    void close()          關閉該輸出流

    void flush()           重新整理該流的緩衝

    void newLine()     寫入一個行分隔符

    void write(char[] cbuf, int off,int len)     寫入字元陣列的某一部分

    void write(int c)     寫入單個字元

    void write(String s,int off,int len)          寫入字串的某一部分

檔案的讀取

檔案的讀取方式一:FileReader();

    1.建立一個FileReader物件。檔案讀取流物件,和指定名稱的檔案相關聯,要保證該檔案是已經存在的,如果不存在會發生異常

    FileReader fr=new FileReader("demo.txt");

    2.呼叫讀取流的物件的read方法

        (1)int ch=fr.read();一次讀一個字元,會自動往下讀。

        (2)讀出所有字元 

     while((ch=fr.read())!=-1){

        System.out.println((char)ch);

     }

    3.關閉流資源,

    fr.close();

 

檔案的讀取方式二:通過字元陣列進行讀取

    1.建立一個FileReader物件。檔案讀取流物件,和指定名稱的檔案相關聯,要保證該檔案是已經存在的,如果不存在會發生異常

    FileReader fr=new FileReader("demo.txt");

    2.定一個字元陣列,用於儲存讀到字元,該rrad(char[])返回的是讀到的字元個數。

    char[] buf=new char[1024];一般定義1024-2個位元組。

    int num=0;

    while((num=fr.read(buf))!=-1){

        System.out.println((new String(buf,0,num));

    }

 

檔案的續寫

傳遞一個true引數,代表不覆蓋已有檔案,並在已知檔案的末尾處進行資料續寫。

FileWriter fw=new FileWriter("demo.txt",true);

換行轉義字元:\r\n

 

IO異常的處理方式

    FileWriter fw=null;
    try {

        fw=new FileWriter("demo.txt");
        fw.write("sdfasd");

    } catch (IOException e) {
        e.printStackTrace();

    }finally { 
        try {

            if(fw!=null)
            fw.close();

        } catch (IOException e) { 
            e.printStackTrace();

        }
}
}

 

ListNumberReader帶有行號的緩衝區

是BufferedReader的直接子類

     LineNumberReader lnr=new LineNumberReader();

    獲取行號:lnr.getLineNumber();

    設定行號從幾開始:lnr.setLineNumber(100);

    1.建立一個字元寫入流物件

        FileReader fr=new FileReader ("a.txt");

    2.將需要被提高效率的流物件作為引數傳遞給緩衝區的建構函式

        LineNumberReader lnfr=new LineNumberReader (fr);

    3.讀取流物件:該緩衝區提供了一個一次讀取一行的方法。當返回null時表示,檔案讀到末尾

        String line=null;

        while((line=lnfr.readLine())!=null) {

            String s=line;

            String linenum=lnfr.getLineNumber();

        }

    4.關閉

        lnfr.close();

自定義帶行號的MyLineNumber

public class MyLineBufferReader extends MyBufferedReader {
    public MyLineBufferReader(Reader r) {
        super(r);
    }
    private int LineNumber;
    public int getLineNumber() {
        return LineNumber;
    }
    public void setLineNumber(int lineNumber) {
        LineNumber = lineNumber;
    }
    public String myReadLine() throws IOException {
        LineNumber++;
        return super.myReadLine();
    }
}

 

自定義一個功能和readline一致的方法,來模擬下BufferedReader()

public class MyBufferedReader extends Reader {
    private Reader r;
    public MyBufferedReader(Reader r) {
        super();
        this.r = r;
    }
    //可以一次讀取一行的方法
    public String myReadLine() throws IOException {
        //定義一個臨時容器。StringBulider容器,應用於儲存字元陣列
        StringBuilder sb=new StringBuilder();
        int ch=0;
        while((ch=r.read())!=-1){
            if(ch=='\r')
                continue;
            if(ch=='\n')
                return sb.toString();
            else
                sb.append((char)ch);
        }
        if(sb.length()!=0)
            return sb.toString();
            return null;
        }
    }
}

 

讀取一個.java檔案,並列印在控制檯上

   

 FileReader fr=null;
    char[] buf=new char[1024];
    int num=0;
    try {
        fr= new FileReader("a.txt"); 
        try {
            while((num=fr.read(buf))!=-1) {
            System.out.print(new String(buf,0,num));
        } catch (IOException e) { 
            e.printStackTrace();
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        try {
            if(fr!=null)
            fr.close();
        } catch (IOException e) { 
            e.printStackTrace();
        }
    }

 

將C盤的一個文字檔案拷貝到D盤(陣列相當於儲存之中的媒介)

步驟:

    1.新建一個檔案用於儲存要被拷貝的檔案

    2.定義讀取流和原始檔關聯

    3.通不過不斷讀寫完成資料儲存

    4.關閉資源

    FileWriter fw=null;
FileReader fr=null;
    try {
        fw=new FileWriter("b.txt");
        fr=new FileReader("a.txt");
        char[] buf=new char[1024];
        int num=0;
        while ((num=fr.read(buf))!=-1) {
            fw.write(buf,0,num);
        }
    }catch (IOException e) {
        e.printStackTrace();
    }finally {
        try {
            fr.close();
        } catch (IOException e) { 
            e.printStackTrace();
        }   
        try {
            fw.close();
        } catch (IOException e) { 
            e.printStackTrace();
        } 
}