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