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:[email protected]/FTP专用目录(server-U).txt"; //此链接即上一链接,通过谷歌浏览器获取,因为包含中文,因此需要转码 String urlPath = "ftp://zhouxiang:[email protected]/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访问网络内容.具体操作可参考其源代码.