源代码分析commons-io-2.0.1-src (一)

Commons 是Apache 的一个开源项目,提供了一些由apache为JDK补充的类和方法.

Commons 网址 http://commons.apache.org/   这里就分析最基础的Commons-io-2.0.1

相关API http://commons.apache.org/io/api-release/index.html

这里分析一些认为比较好的代码.

 

1 org.apache.commons.io.FileUtils.java中FileChannel的使用

 /**
     * 使用FileChannel复制文件<br>
     * Internal copy file method.
     * 
     * @param srcFile  the validated source file, must not be <code>null</code>
     * @param destFile  the validated destination file, must not be <code>null</code>
     * @param preserveFileDate  是否保留原最后修改时间<br>whether to preserve the file date
     * @throws IOException if an error occurs
     */
 private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException {
        if (destFile.exists() && destFile.isDirectory()) {
            throw new IOException("Destination '" + destFile + "' exists but is a directory");
        }

        FileInputStream fis = null;
        FileOutputStream fos = null;
        FileChannel input = null;
        FileChannel output = null;
        try {
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(destFile);
            input  = fis.getChannel();
            output = fos.getChannel();
            long size = input.size();
            long pos = 0;
            long count = 0;
            while (pos < size) {
                count = (size - pos) > FIFTY_MB ? FIFTY_MB : (size - pos);
                pos += output.transferFrom(input, pos, count);
            }
        } finally {
            IOUtils.closeQuietly(output);
            IOUtils.closeQuietly(fos);
            IOUtils.closeQuietly(input);
            IOUtils.closeQuietly(fis);
        }

        if (srcFile.length() != destFile.length()) {
            throw new IOException("Failed to copy full contents from '" +
                    srcFile + "' to '" + destFile + "'");
        }
        if (preserveFileDate) {
            destFile.setLastModified(srcFile.lastModified());
        }
    }

 这里主要注意java.nio.channels.FileChannel.

相关文章

http://wlh269.iteye.com/blog/474068   这个主要讲了使用FileChannel锁定文件.需要补充的是FileChannel锁定文件必需要的文件可写入操作,如果代码中RandomAccessFile 用FileInputStream代替则会抛出

Exception in thread "main" java.nio.channels.NonWritableChannelException
	at sun.nio.ch.FileChannelImpl.tryLock(Unknown Source)
	at java.nio.channels.FileChannel.tryLock(Unknown Source)

 异常.用FileOutputStream代替则可正常运行.

http://www.iteye.com/topic/667457   这里作者试着用FileChannel执行文件的复制操作,这和这里的方法不谋而合.有人提到新的jdk中普通io已经用nio重新实现了一遍,那里的代码还没有认真分析,不知是不是这么回事.抛砖引玉http://www.iteye.com/topic/668311 进一步分析了这部分内容.可以参考.

 

2 org.apache.commons.io.FileUtils.java中关于try.....catch.....finally的使用

    /**
     * 通过字节流的方式从InputStream复制文件到指定文件,如果目标文件不存在则创建,如果存在则覆盖<br>
     * Copies bytes from an {@link InputStream} <code>source</code> to a file
     * <code>destination</code>. The directories up to <code>destination</code>
     * will be created if they don't already exist. <code>destination</code>
     * will be overwritten if it already exists.
     *
     * @param source  the <code>InputStream</code> to copy bytes from, must not be <code>null</code>
     * @param destination  the non-directory <code>File</code> to write bytes to
     *  (possibly overwriting), must not be <code>null</code>
     * @throws IOException if <code>destination</code> is a directory
     * @throws IOException if <code>destination</code> cannot be written
     * @throws IOException if <code>destination</code> needs creating but can't be
     * @throws IOException if an IO error occurs during copying
     * @since Commons IO 2.0
     */
    public static void copyInputStreamToFile(InputStream source, File destination) throws IOException {
        try {
            FileOutputStream output = openOutputStream(destination);
            try {
            	//将OutputStream复制到InputStream大文件(超过2GB),这个方法已经使用了缓存,所以不再需要缓存 如果文件大小超过2GB,则返回-1
                IOUtils.copy(source, output);
            } finally {
                IOUtils.closeQuietly(output);
            }
        } finally {
            IOUtils.closeQuietly(source);
        }
    }

  注意这里的try...finally  因为FileUtils是工具类,所以它不处理这些异常,但为了保证文件被正常关闭,这里使用了try...finally而没有捕捉异常.异常交给调用方法处理.

 

3 org.apache.commons.io.FileUtils.java中关于网络编程的支持

	@Test
	public void testCopyURLToFile() {
		URL sourceUrl = null;
		// String urlPath = "http://www.google.com";
		// String urlPath = "ftp://zhouxiang:good@127.0.0.1/FTP专用目录(server-U).txt";
		//此链接即上一链接,通过谷歌浏览器获取,因为包含中文,因此需要转码
		String urlPath = "ftp://zhouxiang:good@127.0.0.1/FTP%E4%B8%93%E7%94%A8%E7%9B%AE%E5%BD%95(server-U).txt";
		try {
			urlPath = URLDecoder.decode(urlPath, "UTF-8");
			System.out.println("Request: "+urlPath);
			sourceUrl = new URL(urlPath);
			File file = new File(TEST_FILE_PATH);//TEST_FILE_PATH 下载文件路径
			System.out.println("Old last modified time " + new Date(file.lastModified()));
			FileUtils.copyURLToFile(sourceUrl, file);//org.apache.commons.io.FileUtils
			System.out.println("Now last modified time " + new Date(file.lastModified()));
			System.out.println("file size " + file.length());
		} catch (MalformedURLException e1) {
			e1.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

  这里使用org.apache.commons.io.FileUtils.copyURLToFile(URL source, File destination) throws IOException访问网络内容.具体操作可参考其源代码.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值