【一】Apache commons IO包之FileUtils

IO文件操作,可以说是除了JDBC操作之外,日常最常用的功能之一了。IO的读写方式如何,直接影响到系统的性能。很多时候系统的性能瓶颈往往不是出现在对象层面,而是出现在底层的IO层面上。

Apache commosn IO包在input, output包的基础上,提供了一个高效,方便的文件类处理工具:FileUtils,其功能涵盖了所有日常常用的IO操作,由于这个类的部分方法底层是基于Apache commons IO自己的读写流去实现的,所以在性能上会相对高于JDK自带的类(具体原因可以参考这篇文章:IO与文件读写---使用Apache commons io包提高读写效率)

根据Apache commons IO官方的说法,这个类可以提供如下功能:



总体上来说,主要有:

资源的创建、删除
资源的复制、移动
资源的读写
资源的比较
资源的过滤
资源的转换


【二】FileUtils的常用API及解析

资源的创建、删除

目录的创建:
forceMkdir(File directory),这个方法可以在父目录不存在的情况下,连续创建多个目录。但如果同名的目录已经存在或者无权创建,则抛出异常

文件的创建:
touch(File file),这个方法用于创建一个size0的文件,然后迅速关闭输出流。如果文件已经存在则简单地修改一下文件的modify time

目录/文件的删除:
void deleteDirectory(File directory),递归地删除目录及其下的所有内容。


boolean deleteQuietly(File file),相比于JDKdelete()方法有两个不同:首先它不需要被删除目录下的内容为空,其次它不会抛出任何IOException

void forceDelete(File file),强行删除file对象,如果是目录对象则递归删除子目录。如果删除失败则显式地抛出IOException

void forceDeleteOnExit(File file),当JVM退出时,把file对象删除。如果是目录对象则递归删除子目录。

资源的复制、移动

复制目录或文件
copyDirectory(File srcDir, File destDir, FileFilter filter, boolean preserveFileDate),这个方法用于把源目录及其下面的子目录,文件一起拷贝到目标位置(名称可改)。而且该方法允许
在拷贝的过程中进行过滤,指定仅拷贝那些符合条件的资源。最后一个选项用来表明是否保留文件原有的创建、修改日期还是使用最新的日期。

copyDirectoryToDirectory(File srcDir, File destDir),这个方法和上面的区别在于:首先上面的方法是拷贝到destDir的位置,而这个方法是拷贝到destDir“之下的位置。其次上面的方法可以在拷贝的同时改名,这个方法不能,拷贝后仍然使用原来的名称。

copyFile(File srcFile, File destFile, boolean preserveFileDate),类似于上面的copyDirectory方法。

copyFileToDirectory(File srcFile, File destDir, boolean preserveFileDate),类似与上面的copyDirectoryToDirectory方法。

移动目录或文件
moveToDirectory(File srcFile, File destDir, boolean createDestDir),这个方法用于移动一
个文件或者目录到指定位置。

资源的读写

这一部分是FileUtils的精华部分。

读入文件
FileUtils支持对文件以字节数组,字符串,行的方式读入。对应方法分别是:

byte[] readFileToByteArray(File file)
String readFileToString(File file)
String readFileToString(File file, String encoding)
List readLines(File file)
List readLines(File file, String encoding)

这里我们关心的是对于大文件,FileUtils是如何读入的?看看下面的源代码:
/** *//**
* Reads the contents of a file into a String.
* The file is always closed.
*
* @param file the file to read, must not be <code>null</code>
* @param encoding the encoding to use, <code>null</code> means platform default
* @return the file contents, never <code>null</code>
* @throws IOException in case of an I/O error
* @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
*/
public static String readFileToString(File file, String encoding) throws IOException {
InputStream in = null;
try {
in = openInputStream(file);
return String(in, encoding);
} finally {
IOUtils.closeQuietly(in);
}
}

可以见到这个方法调用了IOUtilstoString方法,那么这个过程的底层细节是如何的呢?
public static String toString(InputStream input, String encoding)
throws IOException {
StringWriter sw = new StringWriter();
copy(input, sw, encoding);
return sw.toString();
}

public static void copy(InputStream input, Writer output, String encoding)
throws IOException {
if (encoding == null) {
copy(input, output);
} else {
InputStreamReader in = new InputStreamReader(input, encoding);
copy(in, output);
}
}

/** *//**
* Copy bytes from a large (over 2GB) <code>InputStream</code> to an
* <code>OutputStream</code>.
* <p>
* This method buffers the input internally, so there is no need to use a
* <code>BufferedInputStream</code>.
*
* @param input the <code>InputStream</code> to read from
* @param output the <code>OutputStream</code> to write to
* @return the number of bytes copied
* @throws NullPointerException if the input or output is null
* @throws IOException if an I/O error occurs
* @since Commons IO 1.3
*/
public static long copyLarge(InputStream input, OutputStream output)
throws IOException {
byte[] buffer = newwritelines()方法将什么写入文件 byte[DEFAULT_BUFFER_SIZE];
long count = 0;
int n = 0;
while (-1 != (n = ad(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。