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访问网络内容.具体操作可参考其源代码.