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(内存溢出)。

猜你喜欢

转载自blog.csdn.net/wohiusdashi/article/details/82837808
今日推荐