JAVA語言基礎-面向對象(IO:IO字節流)

20.01_IO流(IO流概述及其分類)

  • 1.概念
    • IO流用來處理設備之間的數據傳輸
    • Java對數據的操做是經過流的方式
    • Java用於操做流的類都在IO包中
    • 流按流向分爲兩種:輸入流,輸出流。
    • 流按操做類型分爲兩種:
      • 字節流 : 字節流能夠操做任何數據,由於在計算機中任何數據都是以字節的形式存儲的
      • 字符流 : 字符流只能操做純字符數據,比較方便。
  • 2.IO流經常使用父類
    • 字節流的抽象父類:
      • InputStream
      • OutputStream
    • 字符流的抽象父類:
      • Reader
      • Writer
  • 3.IO程序書寫
    • 使用前,導入IO包中的類
    • 使用時,進行IO異常處理
    • 使用後,釋放資源

20.02_IO流(FileInputStream)

  • read()一次讀取一個字節
  • FileInputStream fis = new FileInputStream("aaa.txt");   //建立一個文件輸入流對象,並關聯aaa.txt
    int b;                                                  //定義變量,記錄每次讀到的字節
    while((b = fis.read()) != -1) {                         //將每次讀到的字節賦值給b並判斷是不是-1
        System.out.println(b);                              //打印每個字節
    }
    
    fis.close();                                            //關閉流釋放資源

20.03_IO流(read()方法返回值爲何是int)

  • read()方法讀取的是一個字節,爲何返回是int,而不是byte
  • 由於字節輸入流能夠操做任意類型的文件,好比圖片音頻等,這些文件底層都是以二進制形式的存儲的,若是每次讀取都返回byte,有可能在讀到中間的時候遇到111111111
    那麼這11111111是byte類型的-1,咱們的程序是遇到-1就會中止不讀了,後面的數據就讀不到了,因此在讀取的時候用int類型接收,若是11111111會在其前面補上
    24個0湊足4個字節,那麼byte類型的-1就變成int類型的255了這樣能夠保證整個數據讀完,而結束標記的-1就是int類型

    

package com.heima.stream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Demo1_FileInputStream {

	/**
	 * @param args
	 * @throws IOException  
	 * read()方法讀取的是一個字節,爲何返回是int,而不是byte
	 * 
	 * 00010100 00100100 01000001 11111111 0000000
	 * 
	 * 10000001    byte類型-1的原碼
	 * 11111110	   -1的反碼
	 * 11111111    -1的補碼
	 * 
	 * 00000000 00000000 00000000 11111111
	 */
	public static void main(String[] args) throws IOException {
		//demo1();
		FileInputStream fis = new FileInputStream("xxx.txt");	//建立流對象
		int b;
		while((b = fis.read()) != -1) {
			System.out.println(b);
		}
		
		fis.close();
	}

	public static void demo1() throws FileNotFoundException, IOException {
		FileInputStream fis = new FileInputStream("xxx.txt");	//建立流對象
		int x = fis.read();										//從硬盤上讀取一個字節
		System.out.println(x);
		int y = fis.read();
		System.out.println(y);
		int z = fis.read();
		System.out.println(z);
		int a = fis.read();
		System.out.println(a);
		int b = fis.read();
		System.out.println(b);
		fis.close();											//關流釋放資源
	}

}

20.04_IO流(FileOutputStream)

  • write()一次寫出一個字節
  • FileOutputStream fos = new FileOutputStream("bbb.txt"); //若是沒有bbb.txt,會建立出一個
    //fos.write(97);                        //雖然寫出的是一個int數,可是在寫出的時候會將前面的24個0去掉,因此寫出的是一個byte
    fos.write(98);
    fos.write(99);
    fos.close();

20.05_IO流(FileOutputStream追加)

  • A:案例演示
    • FileOutputStream的構造方法寫出數據如何實現數據的追加寫入
  • FileOutputStream fos = new FileOutputStream("bbb.txt",true);    //若是沒有bbb.txt,會建立出一個
    //fos.write(97);                        //雖然寫出的是一個int數,可是在寫出的時候會將前面的24個0去掉,因此寫出的一個byte
    fos.write(98);
    fos.write(99);
    fos.close();

 

package com.heima.stream;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo2_FileOutputStream {

	/**
	 * @param args
	 * @throws IOException 
	 * FileOutputStream在建立對象的時候是若是沒有這個文件會幫我建立出來
	 * 若是有這個文件就會先將文件清空
	 */
	public static void main(String[] args) throws IOException {
		//demo1();
		FileOutputStream fos = new FileOutputStream("yyy.txt",true);	//若是想續寫就在第二個參數傳true
		fos.write(97);
		fos.write(98);
		
		fos.close();
	}

	public static void demo1() throws FileNotFoundException, IOException {
		FileOutputStream fos = new FileOutputStream("yyy.txt");		//建立字節輸出流對象,若是沒有就自動建立一個
		//fos.write(97);				//雖然寫出的是一個int數,可是到文件上的是一個字節,會自動去除前三個8位
		//fos.write(98);
		//fos.write(99);
		fos.write(100);
		fos.close();
	}

}

20.06_IO流(拷貝圖片)

  • FileInputStream讀取
  • FileOutputStream寫出java

    FileInputStream fis = new FileInputStream("致青春.mp3");   //建立輸入流對象,關聯致青春.mp3
    FileOutputStream fos = new FileOutputStream("copy.mp3");//建立輸出流對象,關聯copy.mp3
    
    int b;
    while((b = fis.read()) != -1) {
        fos.write(b);
    }
    
    fis.close();
    fos.close();

20.07_IO流(拷貝音頻文件畫原理圖)

  • A:案例演示
    • 字節流一次讀寫一個字節複製音頻
  • 弊端:效率過低

    

package com.heima.stream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo3_Copy {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		//demo1();
		//demo2();
		//demo3();
	}

	public static void demo3() throws FileNotFoundException, IOException {
		//第二種拷貝,不推薦使用,由於有可能會致使內存溢出
		FileInputStream fis = new FileInputStream("致青春.mp3");		//建立輸入流對象,關聯致青春.mp3
		FileOutputStream fos = new FileOutputStream("copy.mp3");	//建立輸出流對象,關聯copy.mp3
		//int len = fis.available();
		//System.out.println(len);
		
		byte[] arr = new byte[fis.available()];						//建立與文件同樣大小的字節數組
		fis.read(arr);												//將文件上的字節讀取到內存中
		fos.write(arr);												//將字節數組中的字節數據寫到文件上
		
		fis.close();
		fos.close();
	}

	public static void demo2() throws FileNotFoundException, IOException {
		FileInputStream fis = new FileInputStream("致青春.mp3");		//建立輸入流對象,關聯致青春.mp3
		FileOutputStream fos = new FileOutputStream("copy.mp3");	//建立輸出流對象,關聯copy.mp3
		
		int b;
		while((b = fis.read()) != -1) {								//在不斷的讀取每個字節
			fos.write(b);											//將每個字節寫出
		}
		
		fis.close();												//關流釋放資源
		fos.close();
	}

	public static void demo1() throws FileNotFoundException, IOException {
		FileInputStream fis = new FileInputStream("雙元.jpg");		//建立輸入流對象,關聯雙元.jpg
		FileOutputStream fos = new FileOutputStream("copy.jpg");	//建立輸出流對象,關聯copy.jpg
		
		int b;
		while((b = fis.read()) != -1) {								//在不斷的讀取每個字節
			fos.write(b);											//將每個字節寫出
		}
		
		fis.close();												//關流釋放資源
		fos.close();
	}

}

20.08_IO流(字節數組拷貝之available()方法)

  • A:案例演示
    • int read(byte[] b):一次讀取一個字節數組
    • write(byte[] b):一次寫出一個字節數組
    • available()獲取讀的文件全部的字節個數
  • 弊端:有可能會內存溢出設計模式

    FileInputStream fis = new FileInputStream("致青春.mp3");
    FileOutputStream fos = new FileOutputStream("copy.mp3");
    byte[] arr = new byte[fis.available()];                 //根據文件大小作一個字節數組
    fis.read(arr);                                          //將文件上的全部字節讀取到數組中
    fos.write(arr);                                         //將數組中的全部字節一次寫到了文件上
    fis.close();
    fos.close();

    

20.09_IO流(定義小數組)

  • write(byte[] b)
  • write(byte[] b, int off, int len)寫出有效的字節個數

20.10_IO流(定義小數組的標準格式)

  • A:案例演示數組

    • 字節流一次讀寫一個字節數組複製圖片和視頻
    • FileInputStream fis = new FileInputStream("致青春.mp3");ui

      FileOutputStream fos = new FileOutputStream("copy.mp3");加密

      int len; byte[] arr = new byte[1024 * 8]; //自定義字節數組spa

      while((len = fis.read(arr)) != -1) { //fos.write(arr); fos.write(arr, 0, len); //寫出字節數組寫出有效個字節個數 }設計

      fis.close(); fos.close();code

    

package com.heima.stream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo4_ArrayCopy {

	/**
	 * @param args
	 * 第三種拷貝
	 * 定義小數組
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		//demo1();
		//demo2();
		FileInputStream fis = new FileInputStream("致青春.mp3");
		FileOutputStream fos = new FileOutputStream("copy.mp3");
		
		byte[] arr = new byte[1024 * 8];
		int len;
		while((len = fis.read(arr)) != -1) {				//若是忘記加arr,返回的就不是讀取的字節個數,而是字節的碼錶值
			fos.write(arr,0,len);
		}
		
		fis.close();
		fos.close();
	}

	public static void demo2() throws FileNotFoundException, IOException {
		FileInputStream fis = new FileInputStream("xxx.txt");
		FileOutputStream fos = new FileOutputStream("yyy.txt");
		
		byte[] arr = new byte[2];
		int len;
		while((len = fis.read(arr)) != -1) {
			fos.write(arr,0,len);
		}
		
		fis.close();
		fos.close();
	}

	public static void demo1() throws FileNotFoundException, IOException {
		FileInputStream fis = new FileInputStream("xxx.txt");
		byte[] arr = new byte[2];
		int a = fis.read(arr);						//將文件上的字節讀取到字節數組中
		
		System.out.println(a);						//讀到的有效字節個數
		for (byte b : arr) {						//第一次獲取到文件上的a和b
			System.out.println(b);
		}
		System.out.println("-----------------------");
		int c = fis.read(arr);
		System.out.println(c);
		for (byte b : arr) {
			System.out.println(b);
		}
		fis.close();
	}

}

20.11_IO流(BufferedInputStream和BufferOutputStream拷貝)

  • A:緩衝思想
    • 字節流一次讀寫一個數組的速度明顯比一次讀寫一個字節的速度快不少,
    • 這是加入了數組這樣的緩衝區效果,java自己在設計的時候,
    • 也考慮到了這樣的設計思想(裝飾設計模式後面講解),因此提供了字節緩衝區流
  • B.BufferedInputStream
    • BufferedInputStream內置了一個緩衝區(數組)
    • 從BufferedInputStream中讀取一個字節時
    • BufferedInputStream會一次性從文件中讀取8192個, 存在緩衝區中, 返回給程序一個
    • 程序再次讀取時, 就不用找文件了, 直接從緩衝區中獲取
    • 直到緩衝區中全部的都被使用過, 才從新從文件中讀取8192個
  • C.BufferedOutputStream
    • BufferedOutputStream也內置了一個緩衝區(數組)
    • 程序向流中寫出字節時, 不會直接寫到文件, 先寫到緩衝區中
    • 直到緩衝區寫滿, BufferedOutputStream纔會把緩衝區中的數據一次性寫到文件裏
  • D.拷貝的代碼視頻

    FileInputStream fis = new FileInputStream("致青春.mp3");           //建立文件輸入流對象,關聯致青春.mp3
    BufferedInputStream bis = new BufferedInputStream(fis);         //建立緩衝區對fis裝飾
    FileOutputStream fos = new FileOutputStream("copy.mp3");        //建立輸出流對象,關聯copy.mp3
    BufferedOutputStream bos = new BufferedOutputStream(fos);       //建立緩衝區對fos裝飾
    
    int b;
    while((b = bis.read()) != -1) {     
        bos.write(b);
    }
    
    bis.close();                        //只關裝飾後的對象便可
    bos.close();
  • E.小數組的讀寫和帶Buffered的讀取哪一個更快?對象

    • 定義小數組若是是8192個字節大小和Buffered比較的話
    • 定義小數組會略勝一籌,由於讀和寫操做的是同一個數組
    • 而Buffered操做的是兩個數組

20.12_IO流(flush和close方法的區別)

  • flush()方法
    • 用來刷新緩衝區的,刷新後能夠再次寫出
  • close()方法
    • 用來關閉流釋放資源的的,若是是帶緩衝區的流對象的close()方法,不但會關閉流,還會再關閉流以前刷新緩衝區,關閉後不能再寫出

    

package com.heima.stream;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo5_BufferCopy {

	/**
	 * @param args
	 * @throws IOException 
	 * close方法
	 * 具有刷新的功能,在關閉流以前,就會先刷新一次緩衝區,將緩衝區的字節全都刷新到文件上,再關閉,close方法刷完以後就能寫了
	 * flush方法?
	 * 具有刷新的功能,刷完以後還能夠繼續寫
	 */
	public static void main(String[] args) throws IOException {
		//demo1();
		//flush和close方法的區別
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("致青春.mp3"));
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.mp3"));
		
		int b;
		while((b = bis.read()) != -1) {
			bos.write(b);
		}
		bis.close();
		bos.close();
	}

	public static void demo1() throws FileNotFoundException, IOException {
		FileInputStream fis = new FileInputStream("致青春.mp3");				//建立輸入流對象,關聯致青春.mp3
		FileOutputStream fos = new FileOutputStream("copy.mp3");			//建立輸出流對象,關聯copy.mp3
		BufferedInputStream bis = new BufferedInputStream(fis);				//建立緩衝區對象,對輸入流進行包裝讓其變得更增強大
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		
		int b;
		while((b = bis.read()) != -1) {
			bos.write(b);
		}
		
		bis.close();
		bos.close();
	}

}

20.13_IO流(字節流讀寫中文)

  • 字節流讀取中文的問題
    • 字節流在讀中文的時候有可能會讀到半個中文,形成亂碼
  • 字節流寫出中文的問題
    • 字節流直接操做的字節,因此寫出中文必須將字符串轉換成字節數組
    • 寫出回車換行 write("\r\n".getBytes());

    

package com.heima.stream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo6_Chinese {

	/**
	 * @param args
	 * * 字節流讀取中文的問題
			* 字節流在讀中文的時候有可能會讀到半個中文,形成亂碼 
		* 字節流寫出中文的問題
			* 字節流直接操做的字節,因此寫出中文必須將字符串轉換成字節數組 
			* 寫出回車換行 write("\r\n".getBytes());
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		//demo1();
		FileOutputStream fos = new FileOutputStream("zzz.txt");
		fos.write("我讀書少,你不要騙我".getBytes());
		fos.write("\r\n".getBytes());
		fos.close();
	}

	public static void demo1() throws FileNotFoundException, IOException {
		FileInputStream fis = new FileInputStream("yyy.txt");
		byte[] arr = new byte[4];
		int len;
		while((len = fis.read(arr)) != -1) {
			System.out.println(new String(arr,0,len));
		}
		
		fis.close();
	}

}

20.14_IO流(流的標準處理異常代碼1.6版本及其之前)

  • try finally嵌套

    FileInputStream fis = null;
    FileOutputStream fos = null;
    try {
        fis = new FileInputStream("aaa.txt");
        fos = new FileOutputStream("bbb.txt");
        int b;
        while((b = fis.read()) != -1) {
            fos.write(b);
        }
    } finally {
        try {
            if(fis != null)
                fis.close();
        }finally {
            if(fos != null)
                fos.close();
        }
    }

    

package com.heima.stream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo7_TryFinally {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		//demo1();
		try(
			FileInputStream fis = new FileInputStream("xxx.txt");
			FileOutputStream fos = new FileOutputStream("yyy.txt");
			MyClose mc = new MyClose();
		){
			int b;
			while((b = fis.read()) != -1) {
				fos.write(b);
			}
		}
	}

	public static void demo1() throws FileNotFoundException, IOException {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream("xxx.txt");
			fos = new FileOutputStream("yyy.txt");
			
			int b;
			while((b = fis.read()) != -1) {
				fos.write(b);
			}
		}finally {
			try{
				if(fis != null)
					fis.close();
			}finally {							//try fianlly的嵌套目的是能關一個儘可能關一個
				if(fos != null)
					fos.close();
			}
		}
	}

}

class MyClose implements AutoCloseable {
	public void close() {
		System.out.println("我關了");
	}
}

20.15_IO流(流的標準處理異常代碼1.7版本)

  • try close

    try(
        FileInputStream fis = new FileInputStream("aaa.txt");
        FileOutputStream fos = new FileOutputStream("bbb.txt");
        MyClose mc = new MyClose();
    ){
        int b;
        while((b = fis.read()) != -1) {
            fos.write(b);
        }
    }
  • 原理
    • 在try()中建立的流對象必須實現了AutoCloseable這個接口,若是實現了,在try後面的{}(讀寫代碼)執行後就會自動調用,流對象的close方法將流關掉

20.16_IO流(圖片加密)

  • 給圖片加密

    BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.jpg"));
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.jpg"));
    
    int b;
    while((b = bis.read()) != -1) {
        bos.write(b ^ 123);
    }
    
    bis.close();
    bos.close();
  •     將寫出的字節異或上一個數,這個數就是密鑰,解密的時候再次異或就能夠了

    

package com.heima.test;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test1 {

	/**
	 * @param args
	 * @throws IOException 
	 * 將寫出的字節異或上一個數,這個數就是密鑰,解密的時候再次異或就能夠了
	 */
	public static void main(String[] args) throws IOException {
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("copy.jpg"));
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy2.jpg"));
		
		int b;
		while((b = bis.read()) != -1) {
			bos.write(b ^ 123);
		}
		
		bis.close();
		bos.close();
	}

}

20.17_IO流(拷貝文件)

  • 在控制檯錄入文件的路徑,將文件拷貝到當前項目下

    Scanner sc = new Scanner(System.in);
    System.out.println("請輸入一個文件路徑");
    String line = sc.nextLine();                //將鍵盤錄入的文件路徑存儲在line中
    File file = new File(line);                 //封裝成File對象
    FileInputStream fis = new FileInputStream(file);
    FileOutputStream fos = new FileOutputStream(file.getName());
    
    int len;
    byte[] arr = new byte[8192];                //定義緩衝區
    while((len = fis.read(arr)) != -1) {
        fos.write(arr,0,len);
    }
    
    fis.close();
    fos.close();

    

package com.heima.test;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

public class Test2 {

	/**
	 * 在控制檯錄入文件的路徑,將文件拷貝到當前項目下
	 * 
	 * 分析:
	 * 
	 * 1,定義方法對鍵盤錄入的路徑進行判斷,若是是文件就返回
	 * 2,在主方法中接收該文件
	 * 3,讀和寫該文件
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		File file = getFile();					//獲取文件
		BufferedInputStream  bis = new BufferedInputStream(new FileInputStream(file));
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file.getName()));
		
		int b;
		while((b = bis.read()) != -1) {
			bos.write(b);
		}
		
		bis.close();
		bos.close();
	}

	/*
	 * 定義一個方法獲取鍵盤錄入的文件路徑,並封裝成File對象返回
	 * 1,返回值類型File
	 * 2,參數列表無
	 */
	public static File getFile() {
		Scanner sc = new Scanner(System.in);				//建立鍵盤錄入對象
		System.out.println("請輸入一個文件的路徑:");
		while(true) {
			String line = sc.nextLine();					//接收鍵盤錄入的路徑
			File file = new File(line);						//封裝成File對象,並對其進行判斷
			if(!file.exists()) {
				System.out.println("您錄入的文件路徑不存在,請從新錄入:");
			}else if(file.isDirectory()) {
				System.out.println("您錄入的是文件夾路徑,請從新錄入:");
			}else {
				return file;
			}
		}
	}
}

20.18_IO流(錄入數據拷貝到文件)

  • 將鍵盤錄入的數據拷貝到當前項目下的text.txt文件中,鍵盤錄入數據當遇到quit時就退出

    Scanner sc = new Scanner(System.in);
    FileOutputStream fos = new FileOutputStream("text.txt");
    System.out.println("請輸入:");
    while(true) {
        String line = sc.nextLine();
        if("quit".equals(line))
            break;
        fos.write(line.getBytes());
        fos.write("\r\n".getBytes());
    }
    
    fos.close();

    

package com.heima.test;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

public class Test3 {

	/**
	 * 將鍵盤錄入的數據拷貝到當前項目下的text.txt文件中,鍵盤錄入數據當遇到quit時就退出
	 * 
	 * 分析:
	 * 1,建立鍵盤錄入對象
	 * 2,建立輸出流對象,關聯text.txt文件
	 * 3,定義無限循環
	 * 4,遇到quit退出循環
	 * 5,若是不quit,就將內容寫出
	 * 6,關閉流
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		//1,建立鍵盤錄入對象
		Scanner sc = new Scanner(System.in);
		//2,建立輸出流對象,關聯text.txt文件
		FileOutputStream fos = new FileOutputStream("text.txt");
		System.out.println("請輸入數據:");
		//3,定義無限循環
		while(true) {
			String line = sc.nextLine();					//將鍵盤錄入的數據存儲在line中
			//4,遇到quit退出循環
			if("quit".equals(line)) {
				break;
			}
			//5,若是不quit,就將內容寫出
			fos.write(line.getBytes());						//字符串寫出必須轉換成字節數組
			fos.write("\r\n".getBytes());
		}
		//6,關閉流
		fos.close();
	}

}
相關文章
相關標籤/搜索