【Java】【基礎篇】day19:IO流(字節流、轉換流讀寫)

前言

本期任務:畢向東老師Java視頻教程學習筆記(共計25天)


代碼

/*
複製一個圖片
思路:
1,用字節讀取流對象和圖片關聯。
2,用字節寫入流對象創建一個圖片文件。用於存儲獲取到的圖片數據。
3,通過循環讀寫,完成數據的存儲。
4,關閉資源。

*/

import java.io.*;

public class CopyPic {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("picture.png");
        FileOutputStream fos = new FileOutputStream("copy_picture.png");

        byte[] buf = new byte[1024];

        int len = 0;
        while ((len = fis.read(buf)) != -1) {
            fos.write(buf, 0, len);
            fos.flush();
        }

        fos.close();

    }
}
/*
通過緩衝區複製一個.java文件。

*/

import java.io.*;

public class CopyTextByBuf {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("buf.txt");
        FileWriter fw = new FileWriter("buf_copy.txt");

        BufferedReader bufr = new BufferedReader(fr);
        BufferedWriter bufw = new BufferedWriter(fw);

        String line = null;

        while ((line = bufr.readLine()) != null) {
            bufw.write(line);
            bufw.newLine();
            bufw.flush();
        }

        bufr.close();
        bufw.close();

    }
}

import java.io.*;

/*
演示mp3的複製。通過緩衝區。
BufferedOutputStream
BufferedInputStream


*/
public class CopyMp3 {
    public static void main(String[] args) throws IOException {
        BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("夜曲.wav"));
        BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("copy_夜曲.wav"));

        int by = 0;

        while ((by = bufis.read()) != -1) {
            bufos.write(by);
        }

        bufis.close();
        bufos.close();


    }
}

/*
緩衝區的出現是爲了提高流的操作效率而出現的。

所以在創建緩衝區之前,必須要先有流對象。

該緩衝區中提供了一個跨平臺的換行符。
newLine();

*/

import java.io.*;

public class BufferedWriterDemo {
    public static void main(String[] args) throws IOException{
        // 創建一個字符寫入流對象
        FileWriter fw  = new FileWriter("buf.txt");

        //爲了提高字符寫入流效率。加入了緩衝技術。
        //只要將需要被提高效率的流對象作爲參數傳遞給緩衝區的構造函數即可。

        BufferedWriter bufw = new BufferedWriter(fw);

        for (int x=0; x<5; x++){
            bufw.write("abc"+x);
            bufw.newLine();
            bufw.flush();//記住,只要用到緩衝區,就要記得刷新。
        }

        //其實關閉緩衝區,就是在關閉緩衝區中的流對象。
        bufw.close();



    }
}
/*
字符讀取流緩衝區:
該緩衝區提供了一個一次讀一行的方法 readLine,方便於對文本數據的獲取。
當返回null時,表示讀到文件末尾。

readLine方法返回的時候只返回回車符之前的數據內容。並不返回回車符。
*/

import java.io.*;

public class BufferedReaderDemo {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("buf.txt");

        //爲了提高效率。加入緩衝技術。將字符讀取流對象作爲參數傳遞給緩衝對象的構造函數。
        BufferedReader bufr = new BufferedReader(fr);

        String line = null;
        while ((line = bufr.readLine()) != null) {
            System.out.println(line);
        }

        bufr.close();
    }
}

//練習:模擬一個帶行號的緩衝區對象。

import java.io.*;

public class LineNumberReaderDemo {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("buf.txt");

        LineNumberReader lnr = new LineNumberReader(fr);

        String line = null;
//        lnr.setLineNumber(100);
        while ((line = lnr.readLine()) != null) {
            System.out.println(lnr.getLineNumber() + "::" + line);
        }
        lnr.close();

    }
}

/*
讀取鍵盤錄入。
System.out:對應的是標準輸出設備,控制檯。
System.in:對應的標準輸入設備:鍵盤。


需求:
通過鍵盤錄入數據。
當錄入一行數據後,就將該行數據進行打印。
如果錄入的數據是over,那麼停止錄入。

*/

import java.io.*;

public class ReadIn {
    public static void main(String[] args) throws IOException {
        InputStream in = System.in;
        StringBuilder sb = new StringBuilder();

        while (true) {
            int ch = in.read();  // 鍵盤錄入的是字節,擴成int類型
            if (ch == '\r')
                continue;
            if (ch == '\n') {
                String s = sb.toString();
                if ("over".equals(s))
                    break;
                System.out.println(s.toUpperCase());
                sb.delete(0, sb.length());

            }

            else{
                sb.append((char) ch); // 將int類型轉換成字符類型
            }


        }

    }
}

/*
字符流:
FileReader
FileWriter。

BufferedReader
BufferedWriter

字節流:
FileInputStream
FileOutputStream

BufferedInputStream
BufferedOutputStream



通過剛纔的鍵盤錄入一行數據並打印其大寫,發現其實就是讀一行數據的原理。
也就是readLine方法。

能不能直接使用readLine方法來完成鍵盤錄入的一行數據的讀取呢?


readLine方法是字符流BufferedReader類中的方法。

而鍵盤錄入的read方法是字節流InputStream的方法。

那麼能不能將字節流轉成字符流在使用字符流緩衝去的readLine方法呢?


*/

/*
1,
源:鍵盤錄入。
目的:控制檯。

2,需求:想把鍵盤錄入的數據存儲到一個文件中。
源:鍵盤。
目的:文件。

3,需求:想要將一個文件的數據打印在控制檯上。
源:文件。
目的:控制檯。

流操作的基本規律:
最痛苦的就是流對象有很多,不知道該用哪一個。

通過三個明確來完成。

1,明確源和目的。
	源:輸入流。InputStream  Reader
	目的:輸出流。OutputStream  Writer。
2,操作的數據是否是純文本。
	是:字符流。
	不是:字節流。

3,當體系明確後,在明確要使用哪個具體的對象。
	通過設備來進行區分:
	源設備:內存,硬盤。鍵盤
	目的設備:內存,硬盤,控制檯。


1,將一個文本文件中數據存儲到另一個文件中。複製文件。
	源:因爲是源,所以使用讀取流。InputStream Reader
	是不是操作文本文件。
	是!這時就可以選擇Reader
	這樣體系就明確了。

	接下來明確要使用該體系中的哪個對象。
	明確設備:硬盤。上一個文件。
	Reader體系中可以操作文件的對象是 FileReader

	是否需要提高效率:是!。加入Reader體系中緩衝區 BufferedReader.


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




	目的:OutputStream Writer
	是否是純文本。
	是!Writer。
	設備:硬盤,一個文件。
	Writer體系中可以操作文件的對象FileWriter。
	是否需要提高效率:是!。加入Writer體系中緩衝區 BufferedWriter

	FileWriter fw = new FileWriter("b.txt");
	BufferedWriter bufw = new BufferedWriter(fw);


練習:將一個圖片文件中數據存儲到另一個文件中。複製文件。要按照以上格式自己完成三個明確。


---------------------------------------

2,需求:將鍵盤錄入的數據保存到一個文件中。
	這個需求中有源和目的都存在。
	那麼分別分析
	源:InputStream Reader
	是不是純文本?是!Reader

	設備:鍵盤。對應的對象是System.in.
	不是選擇Reader嗎?System.in對應的不是字節流嗎?
	爲了操作鍵盤的文本數據方便。轉成字符流按照字符串操作是最方便的。
	所以既然明確了Reader,那麼就將System.in轉換成Reader。
	用了Reader體系中轉換流,InputStreamReader

	InputStreamReader isr = new InputStreamReader(System.in);

	需要提高效率嗎?需要!BufferedReader
	BufferedReader bufr = new BufferedReader(isr);



	目的:OutputStream  Writer
	是否是存文本?是!Writer。
	設備:硬盤。一個文件。使用 FileWriter。
	FileWriter fw = new FileWriter("c.txt");
	需要提高效率嗎?需要。
	BufferedWriter bufw = new BufferedWriter(fw);


	**************
	擴展一下,想要把錄入的數據按照指定的編碼表(utf-8),將數據存到文件中。

	目的:OutputStream  Writer
	是否是存文本?是!Writer。
	設備:硬盤。一個文件。使用 FileWriter。
	但是FileWriter是使用的默認編碼表。GBK.

	但是存儲時,需要加入指定編碼表utf-8。而指定的編碼表只有轉換流可以指定。
	所以要使用的對象是OutputStreamWriter。
	而該轉換流對象要接收一個字節輸出流。而且還可以操作的文件的字節輸出流。FileOutputStream

	OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");

	需要高效嗎?需要。
	BufferedWriter bufw = new BufferedWriter(osw);

	所以,記住。轉換流什麼使用。字符和字節之間的橋樑,通常,涉及到字符編碼轉換時,
	需要用到轉換流。


練習:將一個文本數據打印在控制檯上。要按照以上格式自己完成三個明確。



*/

import java.io.*;

public class TransStreamDemo {
    public static void main(String[] args) throws IOException {
//        // 獲取鍵盤對象
//        InputStream in = System.in;
//
//        // 將字節流對象轉換成字符流對象,使用轉換流:InputStreamReader
//        InputStreamReader isr = new InputStreamReader(in);
//
//        // 爲了提高效率,將字符串進行緩衝區技術高效操作,使用BufferReader
//        BufferedReader bufr = new BufferedReader(isr);

        // 鍵盤的最常見寫法
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

//        同理
//        OutputStream out = System.out;
//        OutputStreamWriter osw = new OutputStreamWriter(out);
//        BufferedWriter bufw = new BufferedWriter(osw);

        // 控制檯輸出的最常見寫法
        BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

        String line = null;

        while ((line = bufr.readLine()) != null) {
            if ("over".equals(line))
                break;
            bufw.write(line.toUpperCase());
            bufw.newLine();
            bufw.flush();
        }

        bufr.close();

    }
}
/*
裝飾設計模式:
當想要對已有的對象進行功能增強時,
可以定義類,將已有對象傳入,基於已有的功能,並提供加強功能。
那麼自定義的該類稱爲裝飾類。

裝飾類通常會通過構造方法接收被裝飾的對象。
並基於被裝飾的對象的功能,提供更強的功能。


*/

class Person{
    public void chiFan(){
        System.out.println("喫飯");
    }
}

class SuperPerson{
    private Person p;
    SuperPerson(Person p){
        this.p = p;
    }

    public void superChiFan(){
        System.out.println("開胃酒");
        p.chiFan();
        System.out.println("甜點");
        System.out.println("來一根");
    }
}

public class 裝飾和繼承 {
    public static void main(String[] args) {
        Person p = new Person();

        p.chiFan();

        System.out.println("-----------------");

        SuperPerson sp = new SuperPerson(p);
        sp.superChiFan();
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章