1. 程式人生 > >Java IO之FileChannel初探

Java IO之FileChannel初探

概述

對於檔案的複製,平時我們都是使用輸入輸出流進行操作,利用原始檔創建出一個輸入流,然後利用目標檔案創建出一個輸出流,最後將輸入流的資料讀取寫入到輸出流中。這樣也是可以進行操作的。但是利用fileChannel是很有用的一個方式。它能直接連線輸入輸出流的檔案通道,將資料直接寫入到目標檔案中去。

優勢

可防止OOM(記憶體溢位),高效率(後面詳解)

使用

下面以複製500多M的一個本地檔案主例。

方法一:使用普通方式

程式碼如下

    /**
     * 普通的檔案複製方法
     *
     * @param fromFile 原始檔
     * @param toFile   目標檔案
     * @throws FileNotFoundException 未找到檔案異常
     */
    public static void fileCopyNormal(File fromFile, File toFile) throws FileNotFoundException {
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            inputStream = new BufferedInputStream(new FileInputStream(fromFile));
            outputStream = new BufferedOutputStream(new FileOutputStream(toFile));
            byte[] bytes = new byte[1024];
            int i;
            //讀取到輸入流資料,然後寫入到輸出流中去,實現複製
            while ((i = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, i);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null)
                    inputStream.close();
                if (outputStream != null)
                    outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

 

測試方法

	public static void main(String[] args) throws FileNotFoundException {
		long start = System.currentTimeMillis();
		File src = new File("F:\\oxygen.zip");
		File dest = new File("F:\\copy_oxygen.zip");
		fileCopyNormal(src,dest);
		long end = System.currentTimeMillis();
		System.out.println("用時:"+(end -start)+" ms");
	}

執行結果

用時:659 ms

方式二:使用filechannel進行檔案複製

程式碼如下

	  /**
     * 用filechannel進行檔案複製
     *
     * @param fromFile 原始檔
     * @param toFile   目標檔案
     */
    public static void fileCopyWithFileChannel(File fromFile, File toFile) {
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        FileChannel fileChannelInput = null;
        FileChannel fileChannelOutput = null;
        try {
            fileInputStream = new FileInputStream(fromFile);
            fileOutputStream = new FileOutputStream(toFile);
            //得到fileInputStream的檔案通道
            fileChannelInput = fileInputStream.getChannel();
            //得到fileOutputStream的檔案通道
            fileChannelOutput = fileOutputStream.getChannel();
            //將fileChannelInput通道的資料,寫入到fileChannelOutput通道
            fileChannelInput.transferTo(0, fileChannelInput.size(), fileChannelOutput);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileInputStream != null)
                    fileInputStream.close();
                if (fileChannelInput != null)
                    fileChannelInput.close();
                if (fileOutputStream != null)
                    fileOutputStream.close();
                if (fileChannelOutput != null)
                    fileChannelOutput.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

測試方法

	public static void main(String[] args) throws FileNotFoundException {
		long start = System.currentTimeMillis();
		File src = new File("F:\\oxygen.zip");
		File dest = new File("F:\\copy_oxygen.zip");
		fileCopyWithFileChannel(src,dest);
		long end = System.currentTimeMillis();
		System.out.println("用時:"+(end -start)+" ms");
	}

執行結果

用時:340 ms

總結

使用FileChannel 效率快近一倍,並可以有效的防止OOM(記憶體溢位)。