JAVA之IO流

2020-08-12 22:36:44

位元組流

1.1 IO流的概述

	IO流用來處理裝置之間的數據傳輸
	Java對數據的操作是通過流的方式
	Java用於操作流的物件都在IO包中 java.io

1.2 IO流分類

* 按照數據流向 站在記憶體角度
		輸入流	讀入數據
		輸出流	寫出數據
* 按照數據型別
		位元組流 可以讀寫任何型別的檔案 比如音訊 視訊  文字檔案
		字元流 只能讀寫文字檔案

1.3 IO流基礎類別概述

	* IO流基礎類別概述
		a:位元組流的抽象基礎類別:
			InputStream ,OutputStream。
		b:字元流的抽象基礎類別:
			Reader , Writer。
		注:由這四個類派生出來的子類名稱都是以其父類別名作爲子類名的後綴。
		如:InputStream的子類FileInputStream。
		如:Reader的子類FileReader。

1.4 IO流的分類:

* 按照流向進行劃分
 		輸入流
 		輸出流
* 按照操作的數據型別進行劃分
- 位元組流
- 位元組輸入流	InputStream		讀
- 位元組輸出流	OutputStream	寫
- 字元流
- 字元輸入流	Reader			讀
- 字元輸出流	Writer			寫

1.5 IO流(FileOutputStream寫出數據)(寫)

* 構造方法
	FileOutputStream(File file) 在某個路徑下的檔案
	FileOutputStream(String name) 傳入檔案名字,若沒有該檔案則自動建立

	注意事項:
	* 建立位元組輸出流物件了做了幾件事情?
		a:呼叫系統資源建立a.txt檔案
	  	b:建立了一個fos物件
	  	c:把fos物件指向這個檔案
	  	
	* 爲什麼一定要close()?

        a: 通知系統釋放關於管理a.txt檔案的資源
		b: 讓Io流物件變成垃圾,等待垃圾回收器對其回收

1.6 IO流(FileOutputStream的三個write()方法)

* FileOutputStream的三個write()方法
	public void write(int b):寫一個位元組  超過一個位元組 砍掉前面的位元組
	public void write(byte[] b):寫一個位元組陣列
	public void write(byte[] b,int off,int len):寫一個位元組陣列的一部分

1.7 IO流(FileInputStream讀取數據)

* int read():一次讀取一個位元組
        如果沒有數據返回的就是-1
* int read(byte[] b):一次讀取一個位元組陣列
		返回的int型別的值表示的意思是讀取到的位元組的個數,如果沒有數據了就返回-1

1.8 IO流(位元組流複製檔案)

例:
	A:案例演示:	位元組流一次讀寫一個位元組複製文字檔案
	
	 分析:
    - a: 建立位元組輸入流物件和位元組輸出流物件
	- b: 頻繁的讀寫操作
	- c: 釋放資源

方式1:基本位元組流一次讀寫一個位元組
public class CopyFile {
    public static void main(String[] args) throws IOException {
              FileInputStream in = new FileInputStream("MyTest.java");
        FileOutputStream out = new FileOutputStream("E:\\MyTest.java");
               int len=0;
        while ((len=in.read())!=-1){
            out.write(len);
            out.flush();
        }
        
        in.close();
        out.close();

    }
}
方式2:基本位元組流一次讀寫一個位元組陣列
public class MyTest {
    public static void main(String[] args) throws IOException {
               FileInputStream in = new FileInputStream("demo.mp3");
        FileOutputStream out = new FileOutputStream("E:\\曾經的你2.mp3");
             byte[] bytes = new byte[1024 * 8];
        int len = 0;
        while ((len = in.read(bytes)) != -1) {
            out.write(bytes, 0, len);
            out.flush();
        }
     
        in.close();
        out.close();
    }
}

1.9 IO流(BufferedOutputStream寫出數據)

* 緩衝思想
	位元組流一次讀寫一個數組的速度明顯比一次讀寫一個位元組的速度快很多,
	這是加入了陣列這樣的緩衝區效果,java本身在設計的時候,
	也考慮到了這樣的設計思想(裝飾設計模式後面講解),所以提供了位元組緩衝區流
* BufferedOutputStream的構造方法
	檢視API
	BufferedOutputStream(OutputStream out)

1.9 IO流(BufferedInputStream讀取數據)

例子:
高效位元組流一次讀寫一個位元組
public class MyTest {
    public static void main(String[] args) throws IOException {
               BufferedInputStream bfr = new BufferedInputStream(new FileInputStream("demo.mp3"));
        BufferedOutputStream bfw = new BufferedOutputStream(new FileOutputStream("demo2.mp3"));
               int len=0;
              while ((len=bfr.read())!=-1){
            bfw.write(len);
        }
        bfr.close();
        bfw.close();
    }
}
方式4:高效位元組流一次讀寫一個位元組陣列

	public class MyTest {
    public static void main(String[] args) throws IOException {
         BufferedInputStream bfr = new BufferedInputStream(new FileInputStream("demo.mp3"));
        BufferedOutputStream bfw = new BufferedOutputStream(new FileOutputStream("demo2.mp3"));
               int len=0;
        byte[] bytes = new byte[1024 * 8];
        while ((len=bfr.read(bytes))!=-1){
            bfw.write(bytes,0,len);
        }
        bfr.close();
        bfw.close();
    }
}

字元流------------------------------------------------------------------------------------------------------------------

1.1 IO流(轉換流OutputStreamWriter的使用)

* OutputStreamWriter的構造方法
  OutputStreamWriter(OutputStream out):根據預設編碼(GBK)把位元組流的數據轉換爲字元流
  OutputStreamWriter(OutputStream out,String charsetName):根據指定編碼把位元組流數據轉換爲字元流

1.2 IO流(字元流的5種寫數據的方式)

	public void write(int c) 寫一個字元
	public void write(char[] cbuf) 寫一個字元陣列
	public void write(char[] cbuf,int off,int len) 寫一個字元陣列的 一部分
	public void write(String str) 寫一個字串
	public void write(String str,int off,int len) 寫一個字串的一部分

1.3 IO流(轉換流InputStreamReader的使用)

* InputStreamReader的構造方法
	InputStreamReader(InputStream is):用預設的編碼(GBK)讀取數據
	InputStreamReader(InputStream is,String charsetName):用指定的編碼讀取數據

1.4 IO流(字元流的2種讀數據的方式)

* 方法概述
	public int read() 一次讀取一個字元
	public int read(char[] cbuf) 一次讀取一個字元陣列 如果沒有讀到 返回-1

1.5 IO流(FileWriter和FileReader複製文字檔案)

* FileReader和FileWriter的出現
	轉換流的名字比較長,而我們常見的操作都是按照本地預設編碼實現的,
	所以,爲了簡化我們的書寫,轉換流提供了對應的子類。	
	FileWriter
	FileReader
* 字元流便捷類:	因爲轉換流的名字太長了,並且在一般情況下我們不需要制定字元集,
                 於是java就給我們提供轉換流對應的便捷類
    轉換流							便捷類
- OutputStreamWriter	-------		FileWriter
- InputStreamReader	-------		FileReader

1.6 Io流(字元緩衝流的基本使用)

 高效的字元流
	  高效的字元輸出流:	BufferedWriter
	  		     構造方法:	public BufferedWriter(Writer w)
	 高效的字元輸入流:	BufferedReader
	 		    構造方法:   public BufferedReader(Reader e)

1.7 IO流(字元緩衝流的特殊功能)

* 字元緩衝流的特殊功能
	BufferedWriter:	public void newLine():根據系統來決定換行符 具有系統相容性的換行符
	BufferedReader:	public String readLine():一次讀取一行數據  是以換行符爲標記的 讀到換行符就換行 沒讀到數據返回null
	包含該行內容的字串,不包含任何行終止符,如果已到達流末尾,則返回 null
例子(一):
基本的流一次一個字元
 public class MyTest2 {
    public static void main(String[] args) throws IOException {
        
        InputStreamReader in = new InputStreamReader(new FileInputStream("aa.java"));
        OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("demo.java"));
               int len=0;
        while ((len=in.read())!=-1){
            out.write(len);
            out.flush();
        }

        in.close();
        out.close(); 
    }
}
基本的流一次一個字元陣列

public class MyTest {
    public static void main(String[] args) throws IOException {
             FileReader in = new FileReader("aa.java");
        FileWriter out = new FileWriter("demo.java");
        char[] chars=new char[1000];
        int len=0;
        while ((len=in.read(chars))!=-1){
            out.write(chars,0,len);
            out.flush();
        }

        in.close();
        out.close();

    }
}
 高效的流一次一個字元
public class MyTest {
    public static void main(String[] args) throws IOException {
             BufferedReader bfr = new BufferedReader(new FileReader("aa.txt"));
        BufferedWriter bfw = new BufferedWriter(new FileWriter("aaa.txt"));
        int len = 0;
        while ((len=bfr.read()) != -1) {
            bfw.write(len);
            bfw.flush();
        }

        bfr.close();
        bfw.close();

    }
}
高效的流一次一個字元陣列
public class MyTest {
    public static void main(String[] args) throws IOException {
             BufferedReader bfr = new BufferedReader(new FileReader("aa.txt"));
        BufferedWriter bfw = new BufferedWriter(new FileWriter("aaa.txt"));

        char[] chars = new char[1024];
        int len = 0;
        while ((len=bfr.read(chars)) != -1) {
            bfw.write(chars, 0, len);
            bfw.flush();
        }

        bfr.close();
        bfw.close();

    }
}
 高效的流一次一行字串
public class MyTest1 {
    public static void main(String[] args) throws IOException {
               BufferedReader bfr = new BufferedReader(new FileReader("aa.java"));
        BufferedWriter bfw = new BufferedWriter(new FileWriter("aaa.java"));
                String line=null;
        while ((line=bfr.readLine())!=null){
            bfw.write(line);
            bfw.newLine();
h)             bfw.flush();
        }
        bfr.close();
        bfw.close();

    }
}
例子(二):
程式設計序,複製多層資料夾
public class test1 {
    public static void main(String[] args) throws IOException {
        File file = new File("C:\\Users\\優小熊Xx\\Desktop\\aa");
        File newfile = new File("C:\\Users\\優小熊Xx\\Desktop\\bbb");
        if(!newfile.exists()){
            newfile.mkdir();
        }
        copyfile(file,newfile);
    }
    private static void copyfile(File file, File newfile) throws IOException {
        File[] listFiles = file.listFiles();
        for (File listFile : listFiles) {
            if(listFile.isFile()){
                String name = listFile.getName();
                FileInputStream in = new FileInputStream(listFile.getAbsolutePath());
                FileOutputStream out = new FileOutputStream(newfile.getAbsolutePath() + "\\" + name);
                byte[] bytes=new byte[1024];
                int len=0;
                while((len=in.read(bytes))!=-1){
                    out.write(bytes,0,len);
                }
                in.close();
                out.close();
            }else{
                String s = listFile.getName();
                File file1 = new File(newfile.getAbsolutePath() + s);
                file1.mkdirs();
                copyfile(listFile,file1);
            }
        }
    }
}
例子(三):
編寫程式,完成鍵盤錄入學生資訊按照總分排序並寫入文字檔案
需求:鍵盤錄入學生資訊(姓名,數學成績,英語成績)
按照總分從高到低存入文字檔案
public class test {
    public static void main(String[] args) throws IOException {
        TreeSet<Student> ts = new TreeSet<>();

        Scanner sc11 = new Scanner(System.in);
        System.out.println("請輸入學生的個數");
        int n = sc11.nextInt();
        for (int i = 1; i <= n; i++) {
            Scanner sc = new Scanner(System.in);
            System.out.println("請輸入第" + i + "個學生的姓名");
            String s = sc.nextLine();
            System.out.println("請輸入第" + i + "個學生的數學成績");
            int math = sc.nextInt();
            System.out.println("請輸入第" + i + "個學生的英語成績");
            int English = sc.nextInt();
            Student stu = new Student(s, math, English);
            ts.add(stu);
        }
        /*System.out.println("姓名 數學 英語 總分");
        for (Student t : ts) {
            System.out.println(t);
        }*/
        BufferedWriter writer = new BufferedWriter(new FileWriter(new File("C:\\Users\\優小熊Xx\\Desktop\\xs.txt")));
        writer.write("姓名"+"\t"+"數學"+"\t"+"外語"+"\t"+"總分");
        writer.newLine();
        writer.flush();
        for (Student t : ts) {
            writer.write(t.toString());
            writer.newLine();
            writer.flush();
        }
        writer.close();
    }
}

class Student implements Comparable {
    private String name;
    private int all;

    public Student(String name, int mathgrade, int grade) {
        this.name = name;
        this.mathgrade = mathgrade;
        this.grade = grade;
        this.all = this.grade + this.mathgrade;
    }

    private int mathgrade;

    @Override

    public String toString() {
        return name + "\t" + mathgrade + "\t" + grade + "\t" + all;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return mathgrade == student.mathgrade &&
                grade == student.grade &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, mathgrade, grade);
    }

    private int grade;


    @Override
    public int compareTo(Object o) {
        Student s = (Student) o;
        int num = s.all - this.all;
        int num1 = num == 0 ? s.mathgrade - this.mathgrade : num;
        int num2 = num1 == 0 ? s.grade - this.grade : num1;
        int num3 = num2 == 0 ? s.name.compareTo(this.name) : num2;
        return num3;
    }
}