1. 程式人生 > >javaI/O——轉換流 and 檔案拷貝

javaI/O——轉換流 and 檔案拷貝

一、轉換流
1.轉換流的基本使用
我們前面已經學習了兩種資料流了:位元組流和字元流。其實這兩種流是可以相互轉換的。
OutputStreamWriter:將位元組輸出流變為字元輸出流;
InputStreamReader:將位元組輸入流變為字元輸入流;
下面我們來看看這兩個類的構造方法:
輸出流:
a.public class OutputStreamWriter extends Writer
b.public OutputStreamWriter(OutputStream in)
傳的是位元組流的物件
輸入流:
a.public class InputStreamReader extends Reader
b.public InputSreamreader(InputStream in)
eg:

//字元流與位元組流的相互轉化
public class TestOutputStreamWriter {
    public static void main(String[] args) throws Exception {
        //位元組流->字元流  編碼
        //字元流->位元組流  解碼

        //1.建立字元流:
        File srcFile = Paths.get("E:", "learn", "javaio", "a1").toFile();//準備檔案
        File destFile = Paths.get("E:", "learn", "javaio", "a3").toFile();//讀的檔案
        try(
                FileInputStream inputStream = new FileInputStream(srcFile);//準備輸入流物件
                FileOutputStream outputStream = new FileOutputStream(destFile);//準備輸出流物件
                InputStreamReader reader = new InputStreamReader(inputStream);//將位元組流物件傳到方法中-》轉化為字元流
                //下面就可以用reader按照字元流讀了
                OutputStreamWriter writer = new OutputStreamWriter(outputStream)//將位元組輸出流作為引數傳遞-》最後一個省略分號
        ) {
            //按照字元讀取
            char[] buff = new char[1024];//不要開闢太大,這個空間是會在記憶體開闢的
            int len = -1;
            //在讀取內容的時候,將內容放進字元陣列中,同時返回讀取的個數,當沒有資料了但還在讀,這個時候就返回-1,所以用-1來判斷是否還在讀取資料
            while ((len = reader.read(buff)) != -1) {
                writer.write(buff,0,len);
            }
        } catch (Exception e) {
        }
    }
}

綜合案例(重要)——檔案拷貝:
方法一:在程式中開闢一個數組,該陣列長度為檔案長度,將所有資料一次性讀取到該陣列進行輸出儲存

////檔案拷貝方法1:
//public class CopyFile {
//    public static void main(String[] args) {
//        //   原檔案--》目標檔案
//        try{
//        String src = args[0];
//        String dest = args[1];
//        cp(src,dest);
//        }catch(ArrayIndexOutOfBoundsException e){
//            System.out.println("引數不符合要求:srcFilePath destFilePath");
//        }
//    }
//
//    //拷貝檔案的整個方法
//    public static void cp(String srcFilePath, String destFilePath) {//引數是:原檔案,目標檔案
//        checkArguments(srcFilePath);
//        checkArguments(destFilePath);
//        checkFileExists(srcFilePath);//原檔案要存在
//        checkFileNotExists(destFilePath);//目標檔案要不存在
//        File srcFile=Paths.get(srcFilePath).toFile();
//        File destFile=Paths.get(destFilePath).toFile();
//        //拷貝
//        copy(srcFile,destFile);
//
//    }
//
//    //拷貝的方法
//    public static void copy(File srcFile,File destFile){
//        try(FileInputStream in=new FileInputStream(srcFile);
//            FileOutputStream out=new FileOutputStream(destFile)
//        ){
//            //增強版 帶緩衝區
//            byte[] buff=new byte[1024];
//            int len;
//            while((len=in.read(buff))!=-1){
//                out.write(buff,0,len);
//            }
//        }catch (Exception e){
//            System.out.println(e.getMessage());
//        }
//    }
//
//    //1.檢查引數
//    private static void checkArguments(String args) {
//        if (args == null || args.isEmpty()) {
//            throw new IllegalArgumentException("引數不能為空");
//        }
//    }
//
//    //2.檢查檔案是否存在並且這個檔案是普通檔案
//    private static void checkFileExists(String filePath) {
//        Path path = new Paths.get(filePath);
//        File file = path.toFile();
//        if (!(file.exists() && file.isFile())) {
//            throw IllegalArgumentException(filePath + "not exsits");
//        }
//    }
//
//    //3.只是檢查這個檔案是否存在
//    private static void checkFileNotExists(String filePath) {
//        Path path = new Paths.get(filePath);
//        File file = path.toFile();
//        if ((file.exists())) {
//            throw IllegalArgumentException(filePath + "exsits");
//        }
//    }
//}

方法二:採用邊讀編寫的方式完成

//檔案拷貝方法2:
public class CopyFile{
    //檔案複製
    public static void copy(String srcFilePath,String destFilePath){
        //1.判斷路徑是否為空(引數檢驗)
        if(srcFilePath==null||srcFilePath.isEmpty()){
            throw new IllegalArgumentException("srcFilePath must not null");
        }
        if(destFilePath == null||destFilePath.isEmpty()){
            throw  new IllegalArgumentException("destFilePath must not null");
        }
        //檔案校驗以及準備工作
        File srcFile=Paths.get(srcFilePath).toFile();
        File destFile=Paths.get(destFilePath).toFile();
        //2.原檔案不存在或者為目錄
        if(!srcFile.exists()||!srcFile.isFile()){
            throw new IllegalArgumentException("srcFilePath file not exists or not file");
        }
        //3.判斷目標檔案的目錄是否存在。如果不存在並且不能建立那檔案不可以拷貝
        //我們的輸出流只能夠建立檔案但是不能建立目錄,所以前提的保證這個目錄是存在的
        File parentFile=destFile.getParentFile();
        if(!parentFile.exists()){
            if(!parentFile.mkdirs()){
                throw new RuntimeException("can't create"+parentFile.getAbsolutePath()+"directory");
            }
        }
        //開始複製
        try(
                FileInputStream in=new FileInputStream(srcFile);
                FileOutputStream out=new FileOutputStream(destFile)
                ){
            //以後在讀資料的時候我們都使用緩衝的方法
            //此外注意:緩衝區不要取太大,一般在1k的整數倍就可以了
            byte[] buff=new byte[1024];
            int len=-1;
            while((len=in.read(buff))!=-1){//->讀
                out.write(buff,0,len);//->寫
            }
        }catch (IOException e){
            e.getMessage();
        }
    }

    public static void main(String[] args) {
        String src="E:\\learn\\javaio\\a1";
        String dest="E:\\learn\\javaio\\tashuo\\t1.exe";
        //獲取當前時間戳
        long start = System.currentTimeMillis();
        copy(src,dest);
        long end=System.currentTimeMillis();
        System.out.println((end-start)/1000+" s");
    }
}