1. 程式人生 > >JAVA SE 高階知識學習筆記

JAVA SE 高階知識學習筆記

一、 IO流

IO流用來處理裝置之間的資料傳輸     * Java對資料的操作是通過流的方式     * Java用於操作流的類都在IO包中     * 流按流向分為兩種:輸入流,輸出流。     * 流按操作型別分為兩種:          * 位元組流 : 位元組流可以操作任何資料,因為在計算機中任何資料都是以位元組的形式儲存的          * 字元流 : 字元流只能操作純字元資料,比較方便。

1、FileInputStream 輸入流

package com.szj.FileInputStream;
/*
 * 讀 必須要有需要讀的檔案
 */
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStream_01 {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		FileInputStream fis = new FileInputStream("aaa.txt");
		int b;
		while(( b = fis.read())!=-1) {
			System.out.println(b);
		}
		//demo01();
	}
	public static void demo01() throws IOException {
		FileInputStream fis = new FileInputStream("aaa.txt");	//建立一個流物件,並關聯aaa.txt檔案	
		int x = fis.read();	//讀取aaa.txt中的資訊 每讀取一次向後移動一次
		System.out.println(x);
		int y = fis.read();
		System.out.println(y);
		int z = fis.read();
		System.out.println(z);//當檔案讀完後返回-1
		fis.close();	//關流
	}

}

read()方法讀取的是一個位元組,為什麼返回是int,而不是byte

因為位元組輸入流可以操作任意型別的檔案,比如圖片音訊等,這些檔案底層都是以二進位制形式的儲存的,如果每次讀取都返回byte,有可能在讀到中間的時候遇到111111111 那麼這11111111是byte型別的-1,我們的程式是遇到-1就會停止不讀了,後面的資料就讀不到了,所以在讀取的時候用int型別接收,如果是11111111會在其前面補上 24個0湊足4個位元組,那麼byte型別的-1就變成int型別的255了這樣可以保證整個資料讀完,而結束標記的-1就是int型別

2、FileOutputStream 輸出流

package com.szj.FileOutputStream;

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

/*
 * 寫  不需要有檔案 可直接建立檔案 在寫入
 */
public class FileOutputStream_01 {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		/*
		 * FileOutputStream fos = new FileOutputStream("bbb.txt");
		 * 如果沒有bbb.txt會建立一個新的bbb.txt
		 *如果有bbb.txt會將bbb.txt清空 
		 *
		 *FileOutputStream fos = new FileOutputStream("bbb.txt",true);
		 *不會將bbb.txt清空,如果再次寫入檔案會續寫	
		 */
		FileOutputStream fos = new FileOutputStream("bbb.txt");
		fos.write(97);	//雖然寫的是int數,但是實際是Byte型別 
		fos.write(98);
		fos.close();
	}

}

3、通過輸入流和輸出流進行檔案拷貝

逐個位元組拷貝圖片

package com.szj.Copy;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
 * 拷貝圖片 逐個位元組
 */
public class CopyImg {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		FileInputStream fis = new FileInputStream("a.jpg");	//建立輸入流物件 關聯a.jpg
		FileOutputStream fos = new FileOutputStream("b.jpg");	//建立一個輸出流物件
		
		int b;
		while((b = fis.read())!=-1) {	
			//依次讀取a.jpg的位元組資訊 並且寫入b.jpg檔案中
			fos.write(b);	
		}
		
		fis.close();
		fos.close();
		
	}

}

 一次性所有位元組拷貝 拷貝視訊

package com.szj.Copy;

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

/*
 * 拷貝視訊   一次性所有位元組拷貝
 */
public class CopyAvi {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		FileInputStream fis = new FileInputStream("io.avi");
		FileOutputStream fos = new FileOutputStream("copy.avi");
		
		byte [] arr = new byte[fis.available()]; 	//根據io.avi檔案大小宣告一個數組
		fis.read(arr);		//將檔案中的所有位元組讀入到陣列中
		fos.write(arr);    //將陣列中的位元組一次性寫入copy.avi中
		
		fis.close();
		fos.close();
	}

}

4、通過帶緩衝區的輸入流和輸出流進行檔案拷貝

BufferedInputStream          是對    FileInputStream        功能的增強

BufferedOutputStream        是對     FileOutputStream        功能的增強

public class CopyAvi_Bufferd {
	public static void main(String []args) throws IOException {
		FileInputStream fis = new FileInputStream("io.avi");
		BufferedInputStream bis = new BufferedInputStream(fis);	//對輸入流進行裝飾,使之更強大
		FileOutputStream fos = new FileOutputStream("copy.avi");
		BufferedOutputStream bos = new BufferedOutputStream(fos);	//對輸出流進行裝飾,使之更強大
		
		int b;
		//不再是逐個位元組拷貝
		while((b = bis.read()) != -1) {
			/*
			 * 如果檔案足夠大,read()方法執行一次,就會將檔案上的位元組資料一次性讀取並且
			 * 儲存在BufferedInputStream的緩衝區中、從緩衝區中一個位元組一個位元組的返回b
			 * 
			 * 如果write()一次,先將緩衝區裝滿,然後一股腦的寫到檔案上去
			 * 這麼做減少了到硬碟上讀和寫的操作
			 * 
			 */
			
			bos.write(b);
			//bos.flush(); //需要隨時重新整理緩衝區的內容時用 Flush
		}
		
		bis.close();	//只關閉裝飾後的物件即可 
		bos.close();
		
	}
}

5、IO流Demo

流的標準處理異常程式碼


public class Demo01 {
	/*
	 * IO流的標準異常處理程式碼
	 */
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		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 {
			if(fis != null)
				fis.close();
			if(fos != null)
				fos.close();
		}
		
	}

}

IO流實現圖片加密

public class Demo02 {
	/*
	 * IO流實現圖片加密
	 */
	public static void main(String[] args) throws IOException {
		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 ^ 333); //隨便異或一個數字即可完成加密
		}
		bis.close();
		bos.close();
		
	}
}

在鍵盤錄入檔案路徑,將該檔案拷貝到當前專案下


public class Demo03 {
	/*
	 *  在鍵盤錄入檔案路徑,將該檔案拷貝到當前專案下
	 */
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
		System.out.println("請輸入一個要拷貝的檔案的路徑");
		String line = in.nextLine();
		File fli = new File(line);	//將路徑封裝成一個File物件
		FileInputStream fis = new FileInputStream(fli);
		FileOutputStream fos = new FileOutputStream(fli.getName());
		
		int len;
		byte [] arr =  new byte[8192];
		while( (len = fis.read(arr)) != -1 ) {
			fos.write(arr,0,len);
		}
		
		fis.close();
		fos.close();
	}

}

將鍵盤錄入的資料拷貝到當前專案下的test.txt檔案中

	/*
	 * 將鍵盤錄入的資料拷貝到當前專案下的test.txt檔案中
	 */
	public static void main(String[] args) throws IOException {
		Scanner in = new Scanner(System.in);
		System.out.println("請輸入要拷貝到test.txt檔案下的資料");
		String s = in.nextLine();
		
		FileOutputStream fos = new FileOutputStream("test.txt");
		fos.write(s.getBytes());	//將一個字串轉化為一個位元組陣列byte[]的方法
		fos.close();
	}
	

6、IO字元流

每一次是按照一個字元大小去讀,解決讀取中文字元問題

FileReader()

6.1  字元流讀取 

/*
 * 字元流 
 * 每一次是按照一個字元大小去讀,解決讀取中文字元問題
 */

public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		FileReader fr = new FileReader("a.txt");
		int x;
		while((x = fr.read()) != -1) {
			// read()方法通過編碼表按照字元的大小讀取
			System.out.print( (char)x );
		}
		fr.close();
	}

6.2  字元流寫入

public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		FileWriter fw = new FileWriter("b.txt");
		//FileWriter 內建1024個位元組(2k)的小緩衝區
		fw.write(97);	//自動轉換為字元
		fw.write("可以直接寫字串");	
		fw.close();	
	}

二、 多執行緒

* 1.什麼是執行緒     * 執行緒是程式執行的一條路徑, 一個程序中可以包含多條執行緒     * 多執行緒併發執行可以提高程式的效率, 可以同時完成多項工作 * 2.多執行緒的應用場景     * QQ同時和多個人一起視訊     * 伺服器同時處理多個客戶端請求

多執行緒並行和併發的區別

* 並行就是兩個任務同時執行,就是甲任務進行的同時,乙任務也在進行。(需要多核CPU) * 併發是指兩個任務都請求執行,而處理器只能按受一個任務,就把這兩個任務安排輪流進行,由於時間間隔較短,使人感覺兩個任務都在執行。 * 比如我跟兩個網友聊天,左手操作一個電腦跟甲聊,同時右手用另一臺電腦跟乙聊天,這就叫並行。 * 如果用一臺電腦我先給甲發個訊息,然後立刻再給乙發訊息,然後再跟甲聊,再跟乙聊。這就叫併發。