1. 程式人生 > 實用技巧 >java.io,io流,2020.12.28

java.io,io流,2020.12.28

每日心得

假終於放完了,不過感冒還沒好,班上大部分好了吧,可是我們老師吊了兩天水卻還加重了,不可思議。。

java.io

I/O(Streams)流

通過資料流、序列化和檔案系統提供系統輸入和輸出,這是文件的解釋.這裡有一個概念,Stream-->流,指一種資料運送的方式,流分很多種,有位元組流,字元流;這個包主要用於java-->Input&Output與外面的程式進行輸入或輸出,輸入與輸出是相對的概念,當java是輸入方時,被輸入方則是輸出方,輸出同理;這裡又有InputStreamOutputStream,輸入輸出流.
但這其中也分同一機器,系統中的不同程序通訊使用FileInputStream

&FileOutputStream
還有不同機器即跨機器的通訊.net

InputStream(輸入流抽象類)
  .read();//(核心方法)只能一次讀一個返回一個int,範圍(0-255),如果沒有位元組讀了,到達流的末尾,返回-1;這個方法會阻塞,只能給予三種情況,一返回一個範圍內的正整數,二是返回-1,三丟擲異常,超出這三種情況則會發生阻塞,程式碼會一直停在這裡不會繼續執行下去;

  .read(byte b[]);//返回int,總共讀到的緩衝中有多少位元組數,可以幾個位元組一起讀,緩衝即是b[];

  .read(byte b[],//int off ,int len);off偏移量,指定可以在b中哪裡存存多少,可能b中前面一些資料會有用,所以避免將記憶體佔了

  .skips(long l);//跳過部分不要了,已經讀了,但是沒有使用而已

  .available();//返回int,io流中總共可以讀到多少資料byte

  .close();//關閉流,釋放資源

  .mark(int);//標記讀到位置,可能需要返回來重新讀取

  .reset();//重置到mark的位置再往後面讀

  .markSupported();//返回布林值,能否使用mark方法,有些資料無法使用mark
OutputStream(輸出抽象類)

這裡提到一個概念buffer緩衝器,作一個比較(一個瓶子的資料倒入另一個瓶子,因為瓶口太小,為了方便使用漏斗,當一個瓶子資料倒完時,不一定都在另一個瓶子中,可能有些還在漏斗中,在路上,漏斗類似緩衝;)

  .write(int b);//int四個位元組32位,一次寫一個位元組,低八位,高於八位會去掉(向輸出流寫入一個位元組。要寫入的位元組是引數b的八個低位.b的24個高位將被忽略。)

  .write(byte[]b);//將b.length個位元組從指定的byte陣列寫入此輸出流.write(b)的常規協定是:應該與呼叫 write(b, 0, b.length) 的效果完全相同。

  .write(byte[]b,int offer,int len);//與輸入流概念類似

  .flush();//沖刷,將路上的位元組資料即緩衝器的東西直接衝入目標瓶子(直接衝到重新整理此輸出流並強制寫出所有緩衝的輸出位元組)

  .close();//與輸入流概念一致
File檔案類

通過這個類生成的物件-->某個目錄或者某個目錄下檔案資訊的封裝,並不是直接指向某個檔案,路徑名稱怎麼寫取決於其作業系統的不同而不同。
在這裡還會有一個知識-->檔案分隔符:Windows-->反斜槓,正斜槓也識別;Linux-->正斜槓,不識別反斜槓;所以我們一般使用正斜槓,在java中使用反斜槓需要使用兩個反斜槓表示,因為其使轉義字元的原因,但正斜槓只用寫一個。pathname,路徑名稱;directory,目錄;file,檔案;

  File file=new File("");//裡面可以直接傳一個路徑(pathname),也可以傳一個父目錄(parent)與一個子目錄(child)或者檔案,也可以傳一個uri(抽象路徑名);
  .canRead()//can..的各種方法,在windows中基本為true,linux中不,有許可權碼(可執行,可讀,可寫等);
  .creatNewFile();//返回值為布林值,建立一個new檔案;
  .creatTempFile();//返回值為布林值,生成一個臨時檔案在系統的臨時檔案目錄下;
  .delete();//返回值為布林值,不能直接刪除有檔案或者資料夾的資料夾,若某檔案的流還未關閉,也無法刪除;

  相對路徑:
  .等於(./)表示當前資料夾..表示上一層資料夾,/代表根目錄
  相對於應用程式所執行的那個目錄
  get。。Path();//獲取各種路徑;
  getName();//檔名稱,資料夾名稱;
  可以獲取父檔案(Parent)的名稱再獲取其絕對路徑來使用;
  絕對路徑:
  檔案在總盤上的路徑;

  .is..();//判斷是不是路徑,目錄,檔案是否隱藏等;
  .lastModified();//返回的毫秒數,最後修改時間可以使用new Date()包裝方便檢視;
  .length();//檔案大小;
  .list();//返回一個數組,子檔案列表;
  
  
  //檔案過濾器(可以在這裡面加判斷,根據檔案型別進行過濾,返回false則不放入ss中)
  File file=new File("");
  String[] ss=file.list(new FilenameFilter(){
      public boolean accept(File dir,String name){
      syso("name"+name);
      //return false;
      return name.endWith(.java);
      }

  });
  syso(ss.length);

  .mkdir();//建立當前目錄;
  .mkdirs();//若父目錄不存在,則會一起建立,一般用這個;
  .renameTo(File dest);//重新命名此抽象路徑名錶示的檔案;
FileInputStream
  File file= new File("");
  FileInputSteam fis=new FileInputStream(file);
  //while(true){
  //	int ch=fis.read();//一個一個位元組讀
  //	if(-1==ch){
  //	break;
  //}
  //syso((char)ch);
  //}
  byte[]buffer = new byte[1024];
  while(true){
  int length=fis.read(buffer);//讀位元組陣列
  if(-1==length){
  break;
  }
  syso(new String(buffer,0,length));//可能為空,所以對有效位元組進行拼接
  }
  fis.close();
FileOutputStream
  File file= new File("");
  FileOutputSteam fos=new FileOutputStream(file,true);//後面加一個true表示追加模式,不加為覆蓋模式,預設為覆蓋模式,寫入的資料會覆蓋之前寫的;

  fos.write(97);
  fos.write(10);
  fos.write(13);
  fos.write(98);
  fos.write("hello world\n".getByes());
  fos.close();

寫資料時,可能會報thows FileNotFoundException,這個異常意思是下面兩種情況
1、當前檔案存在,但是無法開啟,或者不能寫入;
2、當前檔案不存在,但是沒辦法建立;(而並不是找不到檔案的異常;它是允許檔案不存在,寫的時候可以建立;)

作業:實現資料夾的複製,資料夾下要有多個資料夾和檔案;(使用遞迴)
遞迴:兩個條件-->自己呼叫自己,要有終止條件;
一個簡單的遞迴實現,階乘
f(x)=x*f(x-1);
x==1 f(1)=1;

  public static int ff(int x){
      if(x==1){
       return 1;
      }
      return x*ff(x-1);
  }

資料夾的複製,我找到了一篇文章十分清晰,"https://www.cnblogs.com/yuhudashen/p/7988831.html"他的程式碼註釋十分明白,很容易看懂,思路是寫了兩方法一個是複製檔案,一個是複製資料夾,在複製資料夾中判斷資料夾裡需要複製的是資料夾還是檔案,再呼叫相應的方法,我這借用一下。我自己打了一遍:

package task;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;



public class CopyFile {

	public static void main(String[] args) throws Exception {
		copy("src", "src2");
		System.out.println("複製完成");

	}
	public static void copy(String src,String des) throws Exception{
		File file1=new File(src);
		File[]fs=file1.listFiles();
		File file2=new File(des);
		if(!file2.exists()){
			file2.mkdirs();
		}
		for(File f:fs){
			if(f.isFile()){
				fileCopy(f.getPath(), des+"\\"+f.getName());
			}else if(f.isDirectory()){
				copy(f.getPath(), des+"\\"+f.getName());//資料夾複製,遞迴呼叫自己
			}
		}
	}
	//檔案複製
	public static void fileCopy(String src,String des) throws Exception{
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(des));
		int i=-1;
		byte[] bt=new byte[2014];
		while((i=bis.read(bt))!=-1){
			bos.write(bt,0,i);
		}
		bis.close();
		bos.close();
	}
}