1. 程式人生 > >八: IO流,資料的讀寫傳輸

八: IO流,資料的讀寫傳輸

IO流概括圖:

 

IO流的分類:

 按流:  

  • 輸入流(InputStream和Reader):從硬碟或者別的地方讀入記憶體
  • 輸出流(OutputStream和Writer):從記憶體裡向硬碟或別的地方輸出

按操作型別:

  • 位元組流(InputStream和OutputStream):    位元組流可以操作任何資料,因為在計算機中資料以位元組的形式儲存
  • 字元流(Reader和Writer):字元流只能操作純字元資料,比如文字,以防亂碼

      以上所述,InputStream、OutputStream、Reader、Writer都是抽象類

緩衝流:

  •  BufferedInputStream、BufferedOutputStream
  • 優點:BufferedInputStream讀取時會建立一個長度為8192的byte陣列,讀完返回-1。不用自己手動建立陣列.

字元轉換流:

  •  InputStreamReader和OutputStreamWriter可以設定編碼,完成不同編碼檔案的轉換    

 

絕對路徑和相對路徑:

  •       絕對路徑:檔案在硬碟上真正存在的路徑,比如:D:\Java\HelloWorld.java
  •       相對路徑:只某個檔案路徑徑和別的檔案的路徑關係 。

使用分隔符解決跨平臺的問題:

 

  •    使用File.separator解決不同系統路徑問題           
  •    分隔符:    windows: \
  •                     linux : /
  •   為了保證程式碼跨平臺,使用File.separator代替分隔符 

 

檔案加密和解密:利用兩次異或的原理

中文亂碼問題: 一箇中文佔兩個位元組,如果一次讀寫入奇數個位元組,就有可能亂碼,這時候推薦使用字元流解決,一次讀一行

字元流讀寫檔案:一次讀一行,記得換行bw.newLine()、重新整理緩衝區bw.flush()

 

Code:

  • test() :使用FileInputStream、FileOutputStream讀取、寫入檔案中的內容
  • test2():使用Buffered緩衝流進行檔案拷貝
  • test3():檔案加密解密,利用兩次異或
  • test4():使用位元組流讀取檔案亂碼問題(一箇中文佔兩個位元組)
  • test5():對亂碼問題給出瞭解決,可使用字元流Writer、Reader
  • test6():使用字元流拷貝文字檔案
  • test7():使用轉換流解決不同檔案編碼問題
  • test8():使用轉換流解決不同檔案編碼問題,亂碼解決
package io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;

import org.junit.Test;


public class IODemo { 
    //定義加密code
    static int code = 88;
    //定義檔案路徑
    static String fileName = "C:"+File.separator+"Users"+File.separator+"李騰"+File.separator+"Desktop"+File.separator+"寫入檔案.txt";
    static String readName = "C:"+File.separator+"Users"+File.separator+"李騰"+File.separator+"Desktop"+File.separator+"讀取檔案.txt";

  //使用FileInputStream、FileOutputStream讀取、寫入檔案中的內容
   @Test
   public void test(){
       FileInputStream fis = null;
       FileOutputStream fos = null;
       //絕對路徑
       String readFile = "D:"+File.separator+"mylog.log";
       String writeFile = "D:"+File.separator+"newWrite.txt";
   try {           
        fos = new FileOutputStream(writeFile,true);    
        fis = new FileInputStream(readFile);
        //定義位元組陣列接收資訊
        byte[] bytes = new byte[6000];
        int temp;
        while((temp = fis.read(bytes))!=-1){
            fos.write(temp);
            //重新整理並寫出所有緩衝位元組
            fos.flush();
        }
    } catch (FileNotFoundException e) {    
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        try {
            fos.close();
            fis.close();
        }
        catch (IOException e) {        
            e.printStackTrace();
        }
    }
   }
   //使用Buffered緩衝流進行檔案拷貝
   @Test
   public void test2(){
       BufferedInputStream bis = null;
       BufferedOutputStream bos = null;
       try {
        bis = new BufferedInputStream(new FileInputStream("D:"+File.separator+"mylog.log"));
        bos = new BufferedOutputStream(new FileOutputStream("D:"+File.separator+"buf.txt"));
        int temp;
        while((temp=bis.read())!=-1){
            bos.write(temp);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }finally{
        try {
            bis.close();
            bos.close();
        } catch (IOException e) {        
            e.printStackTrace();
        }
        
    }
   }
   //檔案加密解密,利用兩次異或
   //JDK7新特性,系統自動close
   @Test
   public void test3(){
       BufferedOutputStream bos = null;
       BufferedInputStream bis = null;
       //加密
       try {
        bis = new BufferedInputStream(new FileInputStream("D:"+File.separator+"IO流.rar"));
        bos = new BufferedOutputStream(new FileOutputStream("D:"+File.separator+"加密.rar"));
        int temp;
        while((temp=bis.read())!=-1){
            bos.write(temp^code);
            bos.flush();
        }        
       } catch (IOException e) {
        e.printStackTrace();
    }
       //解密
       try {
           bis = new BufferedInputStream(new FileInputStream("D:"+File.separator+"加密.rar"));
           bos = new BufferedOutputStream(new FileOutputStream("D:"+File.separator+"解密.rar"));
           int temp;
           while((temp=bis.read())!=-1){
               bos.write(temp^code);
               bos.flush();
           }        
       } catch (IOException e) {
           e.printStackTrace();
       }
   }
   
   //使用位元組流讀取檔案亂碼問題(一箇中文佔兩個位元組)
   //test5對亂碼問題給出瞭解決,可使用字元流Writer、Reader
   @Test
   public void test4(){
       FileOutputStream fos = null;
       FileInputStream fis = null;
       String msg = "好好";
       try {
        fos = new FileOutputStream(fileName);
        fis = new FileInputStream(readName);
        int temp;
        //每次讀三個位元組,也亂碼
        byte[] arr = new byte[3];
        //每次寫三個位元組,因為中文佔兩,所以亂碼
        fos.write(msg.getBytes(),0,3);
        //換行
        fos.write("\r\n".getBytes());
        fos.flush();
        while((temp=fis.read(arr))!=-1){
            System.out.println(new String(arr,0,temp));
        }
        
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
   }
   
  /* 用字元流解決中文亂碼問題
   * BufferdReader可以一次讀一行文字,readLine方法返回null
   * */
   @Test
   public void test5(){
       BufferedReader buf = null;
       FileWriter fw = null;
       BufferedWriter bw = null;
       try {
        buf = new BufferedReader(new FileReader(readName));
        String s;
        //
        bw = new BufferedWriter(new FileWriter(fileName));
        bw.write("我喜歡學習java");
        bw.write(97);
        bw.flush();
        fw = new FileWriter(fileName);
        fw.write("FileWriter寫入");
        fw.flush();
        //
        while((s = buf.readLine())!=null){
//            bw.write(s);
            System.out.print(s);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
   }
   
   //使用字元流拷貝文字檔案
    @Test
    public void test6(){
        BufferedReader br = null;
        BufferedWriter bw = null;
        
        try {
            br = new BufferedReader(new FileReader(readName));
            bw = new BufferedWriter(new FileWriter(fileName));
            String s ;
            while((s=br.readLine())!=null){
                //讀一行
                bw.write(s);
                //讀完換行
                bw.newLine();
                bw.flush();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    //使用轉換流解決不同檔案編碼問題
    //字元流亂碼
    @Test
    public void test7(){
        try(
            //將utf-8的內容寫出到GBK.txt中,發現亂碼
            BufferedReader br= 
            new BufferedReader(new FileReader("D:\\JAVA基礎\\7.15\\1javaSe\\file\\utf-8.txt"));
            BufferedWriter bw= 
            new BufferedWriter(new FileWriter("D:\\JAVA基礎\\7.15\\1javaSe\\file\\GBK.txt"));
            ){
            String msg;
            while((msg=br.readLine())!=null){
                bw.write(msg);
            }
            bw.flush();
        } catch (UnsupportedEncodingException e) {            
            e.printStackTrace();
        } catch (FileNotFoundException e) {        
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    //使用轉換流解決不同檔案編碼問題,亂碼解決
    @Test
    public void test8(){    
        try(
        BufferedReader br =
        new BufferedReader(new InputStreamReader(new FileInputStream("D:\\JAVA基礎\\7.15\\1javaSe\\file\\utf-8.txt"), "utf-8"));
        BufferedWriter bw =
        new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\JAVA基礎\\7.15\\1javaSe\\file\\GBK.txt"),"GBK"));
                
            ){
            String msg;
            while((msg=br.readLine())!=null){
                bw.write(msg);
            }
            bw.flush();
        } catch (UnsupportedEncodingException e) {            
            e.printStackTrace();
        } catch (FileNotFoundException e) {        
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}