1. 程式人生 > >recursion&file&Buffered&I/O流

recursion&file&Buffered&I/O流

遞迴

描述:

遞迴做為一種演算法在程式設計語言中廣泛應用。 一個過程或函式在其定義或說明中有直接或間接呼叫自身的一種方法,它通常把一個大型複雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解。遞迴策略只需少量的程式就可描述出解題過程所需要的多次重複計算,大大地減少了程式的程式碼量。遞迴的能力在於用有限的語句來定義物件的無限集合。一般來說,遞迴需要有邊界條件、遞迴前進段和遞迴返回段。當邊界條件不滿足時,遞迴前進;當邊界條件滿足時,遞迴返回。

遞迴演算法解題相對常用的演算法如普通迴圈等,執行效率較低。因此,應該儘量避免使用遞迴,除非沒有更好的演算法或者某種特定情況,遞迴更為適合的時候。在遞迴呼叫的過程當中系統為每一層的返回點、區域性量等開闢了棧來儲存。遞迴次數過多容易造成棧溢位等。

Java中使用遞迴注意:構造方法不能遞迴使用。

  • 程式碼例項:
    • 斐波那契
      /*for example-Fibonacci*/
      /*思考如何用遞迴實現斐波那契數列的儲存和顯示。*/
      public static int fib(int n) {
      		if (n == 1 || n == 2) {
      			return 1;
      		} else {
      			return fib(n - 1) + fib(n - 2);
      		}
      	}
      
      /*明顯的優勢是將有用的資料儲存在數組裡面。*/
      arr[0] = 1;
      arr[1] = 1;
      for (int x = 2; x < arr.length; x++) {
      	arr[x] = arr[x - 2] + arr[x - 1];			
      }
      
      /*不斷替換a,b對應的資料,資料不保留。*/
      int a = 1;
      int b = 1;
      for (int x = 0; x < 18; x++) {
      	// 每執行一次將a,b對應的資料重新整理一遍。
      	int temp = a;
      	a = b;
      	b = temp + b;
      	System.out.println(a);
      }
      

IO流

描述:

按照流的方式進行輸入輸出,資料被當成無結構的位元組序或字元序列。從流中取得資料的操作稱為提取操作,而向流中新增資料的操作稱為插入操作。用來進行輸入輸出操作的流就稱為IO流…

  • 分類:

    • 流向
      可以這樣理解,流的輸入還是輸出性是相對於記憶體來描述的。相對於記憶體是進入記憶體,則為輸入流–讀取資料;相對於記憶體是流出記憶體,則是輸出流–寫出資料–寫入到外部儲存裝置。
    • 資料型別
      位元組流:位元組輸入流,位元組輸出流。
      字元流:字元輸入流,字元輸出流。

    建議使用位元組流進行檔案的輸入和輸出。

  • FileOutputStream寫出資料

    使用中,主函式必須public static void main(String[] args) throws IOException/try…catch…

    /*for example*/
    		FileOutputStream fos = new FileOutputStream("fos.txt");			
    		fos.write("hello,world.".getBytes());			
    		fos.close();
    
  • FileInputStream讀取資料

    使用中,主函式必須public static void main(String[] args) throws IOException/try…catch…

    /*for example*/
    		FileInputStream fis = new FileInputStream("fos.txt");
    		//way_01:	
    		int by = 0;
    		while((by=fis.read())!=-1) {
    			System.out.print((char)by);
    		}
    
    		//way_02
    		char by = 0;		
    		while ((by = (char) fis.read()) != -1) {
    			System.out.print(by);
    		}
    	
    		//way_03
    			byte[] bys = new byte[1024];
    			int len = 0;
    			while((len=fis.read(bys))!=-1) {
    				System.out.print(new String(bys,0,len));
    			}		
    		fos.close();
    
  • 位元組緩衝區流

    • BufferedOutputStream.
    • BufferedInputStream.

    	//字元緩衝區的使用方法.
    	public static void Way_One(String srcString, String destString)
    			throws IOException {
    		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
    				srcString));
    		BufferedOutputStream bos = new BufferedOutputStream(
    				new FileOutputStream(destString));
    
    		byte[] bys = new byte[1024];
    		int len = 0;
    		while ((len = bis.read(bys)) != -1) {
    			bos.write(bys, 0, len);
    		}
    
    		bos.close();
    		bis.close();
    	}
    
    	
    	public static void Way_Two(String srcString, String destString)
    			throws IOException {
    		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
    				srcString));
    		BufferedOutputStream bos = new BufferedOutputStream(
    				new FileOutputStream(destString));
    
    		int by = 0;
    		while ((by = bis.read()) != -1) {
    			bos.write(by);
    
    		}
    
    	fos.close();
    	fis.close();
    
    
  • 字元流

    描述:位元組流對於資料的複製儲存操作上並沒有什麼區別,但是有操作中文資料的視覺化上不是特別的方便,所以就出現了轉換流,轉換流的作用就是把位元組流轉換字元流來使用。

    • 轉換流就是字元
      字元流 = 位元組流 + 編碼表(註明編碼格式.)
    • 編碼表
      • 就是由字元和對應的數值組成的表。

    編碼表

  • 字串中的編碼

    • IO流中的編碼

      /*for example*/
      /*字元流與位元組流的橋樑*/
      OutputStreamWriter
      
      	是字元的橋樑流以位元組流:向其寫入的字元編碼成使用指定的位元組charset 。 它使用的字符集可以由名稱指定,也可以被明確指定,或者可以接受平臺的預設字符集。
      
      	OutputStreamWriter(OutputStream os):預設編碼,GBK
      	OutputStreamWriter(OutputStream os,String charsetName):指定編碼。
      
      InputStreamReader
      
      	是從位元組流到字元流的橋:它讀取位元組,並使用指定的charset將其解碼為字元 。 它使用的字符集可以由名稱指定,也可以被明確指定,或者可以接受平臺的預設字符集。
       
      	InputStreamReader(InputStream is):預設編碼,GBK.
      	InputStreamReader(InputStream is,String charsetName):指定編碼.
      
      編碼問題
      	儲存的本質問題都是位元組流,解決辦法直接指定編碼格式與之對應即可,或者使用寫入檔案的編碼格式即可。
      
      public static void main(String[] args) throws IOException {
      		
      		// OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
      		// "osw.txt")); // 預設GBK
      		// OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
      		// "osw.txt"), "GBK"); // 指定GBK
      		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
      				"osw.txt"), "UTF-8"); // 指定UTF-8
      		
      	
      		osw.write("中國");		
      		osw.close();
      }
      
      public static void main(String[] args) throws IOException {
      		
      		// InputStreamReader isr = new InputStreamReader(new FileInputStream(
      		// "osw.txt"));
      		// InputStreamReader isr = new InputStreamReader(new FileInputStream(
      		// "osw.txt"), "GBK");
      		InputStreamReader isr = new InputStreamReader(new FileInputStream(
      				"osw.txt"), "UTF-8");
      		
      		int ch = 0;
      		while ((ch = isr.read()) != -1) {
      			System.out.print((char) ch);
      		}
      
      		/*
      		char[] chs = new char[1024];
      		int len = 0;
      		while ((len = isr.read(chs)) != -1) {
      			System.out.print(new String(chs, 0, len));
      		}
      		*/
      		
      		isr.close();
      }
      
      public static void main(String[] args) throws IOException {
      
      	InputStreamReader isr = new InputStreamReader(new FileInputStream(
      			"a.txt"));	
      	OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
      			"b.txt"));
      	
      	/*方式1
      	int ch = 0;
      	while ((ch = isr.read()) != -1) {
      	osw.write(ch);
      	}
      	*/
      
      	/* 方式2*/
      	char[] chs = new char[1024];
      	int len = 0;
      	while ((len = isr.read(chs)) != -1) {
      		osw.write(chs, 0, len);
      		// osw.flush();
      	}
      
      	// 釋放資源
      	osw.close();
      	isr.close();
      }
      
    • 字元流

      Reader
      	|--InputStreamReader
      		|--FileReader
      	|--BufferedReader
      Writer
      	|--OutputStreamWriter
      		|--FileWriter
      	|--BufferedWriter
      

IO流操作結構圖解

  • IO圖解

  • I/O程式碼例項

/*for example*/
/*字元緩衝流
 BufferedWriter:
 		public void newLine():根據系統來決定換行符
 BufferedReader:
 		public String readLine():一次讀取一行資料
 		包含該行內容的字串,不包含任何行終止符,如果已到達流末尾,則返回null.
 */