java實現文件拷貝的七種方式

1. 通過字節流實現文件的拷貝

  /**
     * 通過字節流實現文件的拷貝
     * @param sourcePath 源文件路徑
     * @param targetPath 目標文件路徑
     */
    public static void copyFileByStream(String sourcePath,String targetPath){
        //源文件路徑
        File source = new File(sourcePath);
        //目標文件路徑
        File target = new File(targetPath);

        //如果源文件不存在則不能拷貝
        if(!source.exists()){
            return;
        }
        //如果目標文件目錄不存在則創建
        if(!target.getParentFile().exists()){
            target.getParentFile().mkdirs();
        }

        try {
            //實現文件的拷貝
            InputStream inputStream = new FileInputStream(source);
            OutputStream outputStream = new FileOutputStream(target);
            int temp = 0;
            //每次讀取1024個字節
            byte[] data = new byte[1024];
            //將每次讀取的數據保存到字節數組裏面,並且返回讀取的個數
            while ((temp = inputStream.read(data)) != -1){
                //輸出數組
                outputStream.write(data,0,temp);
            }

            inputStream.close();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

2. 通過字符流實現文件拷貝

使用字符流只能拷貝文本文件

    /**
     * 通過字符流實現文件的拷貝
     *
     * @param sourcePath 源文件路徑
     * @param targetPath 目標文件路徑
     */
    public static void copyFileByReaderAndWriter(String sourcePath, String targetPath) {
        //源文件路徑
        File source = new File(sourcePath);
        //目標文件路徑
        File target = new File(targetPath);

        //如果源文件不存在則不能拷貝
        if (!source.exists()) {
            return;
        }
        //如果目標文件目錄不存在則創建
        if (!target.getParentFile().exists()) {
            target.getParentFile().mkdirs();
        }

        FileReader in = null;
        FileWriter out = null;
        try {
            //字符輸入流和字符輸出流
            in = new FileReader(source);
            out = new FileWriter(target);

            char[] c = new char[1024];
            int temp = 0;
            //每次讀取1024個字符
            while ((temp = in.read(c)) != -1) {
                //輸出到文件
                out.write(c, 0, temp);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //關閉流
            try {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

3. 通過字節緩衝流實現文件拷貝

/**
     * 通過字節緩衝流實現文件的拷貝
     *
     * @param sourcePath 源文件路徑
     * @param targetPath 目標文件路徑
     */
    public static void copyFileByBuffered(String sourcePath, String targetPath){
        //源文件路徑
        File source = new File(sourcePath);
        //目標文件路徑
        File target = new File(targetPath);

        //如果源文件不存在則不能拷貝
        if (!source.exists()) {
            return;
        }
        //如果目標文件目錄不存在則創建
        if (!target.getParentFile().exists()) {
            target.getParentFile().mkdirs();
        }

        InputStream in = null;
        OutputStream out = null;
        try {
            //字節緩衝輸入流和字節緩衝輸出流
            in = new BufferedInputStream(new FileInputStream(source));
            out = new BufferedOutputStream(new FileOutputStream(target));

            byte[] b = new byte[1024];
            int temp = 0;
            //每次讀取一個1024的字節數組
            while((temp = in.read(b)) != -1){
                //輸出到文件
                out.write(b,0,temp);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //關閉流
            try {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

4. 通過字符緩衝流拷貝文件

字符緩衝流只能讀取文本文件

 /**
     * 通過字符緩衝流實現文件的拷貝
     *
     * @param sourcePath 源文件路徑
     * @param targetPath 目標文件路徑
     */
    public static void copyFileByBufferedChar(String sourcePath, String targetPath){
        //源文件路徑
        File source = new File(sourcePath);
        //目標文件路徑
        File target = new File(targetPath);

        //如果源文件不存在則不能拷貝
        if (!source.exists()) {
            return;
        }
        //如果目標文件目錄不存在則創建
        if (!target.getParentFile().exists()) {
            target.getParentFile().mkdirs();
        }

        BufferedReader in = null;
        BufferedWriter out = null;

        try {
            //字符緩衝輸入流和字符緩衝輸出流
            in = new BufferedReader(new FileReader(source));
            out = new BufferedWriter(new FileWriter(target));

            //讀取文件(每次讀取一行)
            String temp = null;
            while((temp = in.readLine()) != null){
                //輸出到文件
                out.write(temp);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //關閉流
            try {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

5. 通過JAVA NIO 非直接緩衝區拷貝文件

   /**
     * 通過JAVA NIO 非直接緩衝區拷貝文件
     *
     * @param sourcePath 源文件路徑
     * @param targetPath 目標文件路徑
     */
    public static void copyFileByChannel(String sourcePath, String targetPath) {
        FileChannel outChannel = null;
        FileChannel inChannel = null;

        FileInputStream fis = null;
        FileOutputStream fos = null;

        try {
            fis = new FileInputStream(sourcePath);
            fos = new FileOutputStream(targetPath);

            //獲取通道
            inChannel = fis.getChannel();
            outChannel = fos.getChannel();

            //分配指定大小的緩衝區
            ByteBuffer buf = ByteBuffer.allocate(1024);

            while (inChannel.read(buf) != -1) {
                //轉換爲讀取數據模式
                buf.flip();
                //寫入到磁盤
                outChannel.write(buf);
                //清空緩衝區
                buf.clear();
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //關閉流
            try {
                if (outChannel != null) {
                    outChannel.close();
                }
                if (inChannel != null) {
                    inChannel.close();
                }
                if (fis != null) {
                    fis.close();
                }
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

6. 通過JAVA NIO 直接緩衝區拷貝文件

/**
     * 通過JAVA NIO 直接緩衝區拷貝文件(內存映射文件)
     *
     * @param sourcePath 源文件路徑
     * @param targetPath 目標文件路徑
     */
    public static void copyFileByChannelBufferd(String sourcePath, String targetPath) {
        FileChannel inChannel = null;
        FileChannel outChannel = null;
        try {
            //獲取通道,StandardOpenOption.READ表示可讀,StandardOpenOption.WRITE表示可寫,StandardOpenOption.CREATE表示可以創建
            inChannel = FileChannel.open(Paths.get(sourcePath), StandardOpenOption.READ);
            outChannel = FileChannel.open(Paths.get(targetPath), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);

            //創建內存映射文件
            MappedByteBuffer inMapped = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
            MappedByteBuffer outMapped = outChannel.map(FileChannel.MapMode.READ_WRITE, 0, inChannel.size());

            //直接操作內存映射文件
            byte[] buf = new byte[inMapped.limit()];
            inMapped.get(buf);
            outMapped.put(buf);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //關閉流
            try {
                if (outChannel != null) {
                    outChannel.close();
                }
                if (inChannel != null) {
                    inChannel.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

7. 通過JAVA NIO 通道傳輸拷貝文件

方式一

 /**
     *  通過JAVA NIO 通道傳輸拷貝文件
     *
     * @param sourcePath 源文件路徑
     * @param targetPath 目標文件路徑
     */
    public static void copyFileByChannelTransfer(String sourcePath, String targetPath) {
        FileChannel inChannel = null;
        FileChannel outChannel = null;
        try {
            //獲取通道
            inChannel = FileChannel.open(Paths.get(sourcePath), StandardOpenOption.READ);
            outChannel = FileChannel.open(Paths.get(targetPath),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);

            inChannel.transferTo(0,inChannel.size(),outChannel);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //關閉流
            try {
                if (outChannel != null) {
                    outChannel.close();
                }
                if (inChannel != null) {
                    inChannel.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

方式二

 /**
     *  通過JAVA NIO 通道傳輸拷貝文件
     *
     * @param sourcePath 源文件路徑
     * @param targetPath 目標文件路徑
     */
    public static void copyFileByChannelTransfer2(String sourcePath, String targetPath) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        FileChannel inChannel = null;
        FileChannel outChannel = null;
        try {
            fis = new FileInputStream(sourcePath);
            fos = new FileOutputStream(targetPath);

            //獲取通道
            inChannel = fis.getChannel();
            outChannel = fos.getChannel();

            inChannel.transferTo(0,inChannel.size(),outChannel);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //關閉流
            try {
                if (outChannel != null) {
                    outChannel.close();
                }
                if (inChannel != null) {
                    inChannel.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

使用示例

        String source = "e:\\demo\\縱天神帝.txt";
        String target = "e:\\demo\\";
        long time1 = System.currentTimeMillis();
        copyFileByStream(source, target + "1.txt");
        System.out.println("通過字節流實現文件的拷貝耗時:" + (System.currentTimeMillis() - time1));

        long time2 = System.currentTimeMillis();
        copyFileByReaderAndWriter(source, target + "2.txt");
        System.out.println("通過字符流實現文件的拷貝耗時:" + (System.currentTimeMillis() - time2));

        long time3 = System.currentTimeMillis();
        copyFileByBuffered(source, target + "3.txt");
        System.out.println("通過字節緩衝流實現文件的拷貝耗時:" + (System.currentTimeMillis() - time3));

        long time4 = System.currentTimeMillis();
        copyFileByBufferedChar(source, target + "4.txt");
        System.out.println("通過字符緩衝流實現文件的拷貝耗時:" + (System.currentTimeMillis() - time4));

        long time5 = System.currentTimeMillis();
        copyFileByChannel(source, target + "5.txt");
        System.out.println("通過JAVA NIO通道(非直接緩衝區)實現文件的拷貝耗時:" + (System.currentTimeMillis() - time5));

        long time6 = System.currentTimeMillis();
        copyFileByChannelBufferd(source, target + "6.txt");
        System.out.println("通過JAVA NIO通道(直接緩衝區)實現文件的拷貝耗時:" + (System.currentTimeMillis() - time6));

        long time7 = System.currentTimeMillis();
        copyFileByChannelTransfer(source, target + "7.txt");
        System.out.println("通過JAVA NIO通道傳輸實現文件的拷貝耗時:" + (System.currentTimeMillis() - time7));

        long time8 = System.currentTimeMillis();
        copyFileByChannelTransfer(source, target + "8.txt");
        System.out.println("通過JAVA NIO通道傳輸2實現文件的拷貝耗時:" + (System.currentTimeMillis() - time8));

通過測試發現,使用JAVA NIO通道傳輸、JAVA NIO通道直接緩衝區以及字節緩衝流拷貝文件效率最高

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章