Back

(java 往日的翻译) common-io Best practices

发布时间: 2008-05-06 08:14:00

Best practices 最佳实践
This document presents a number of 'best practices' in the IO area.
本文档包含了一些IO领域的 ‘最佳实践’
java.io.File
Often, you have to deal with files and filenames. There are many things that can go wrong:
我们通常需要处理文件和文件名。有很多地方会出错:
* A class works in Unix but doesn't on Windows (or vice versa)
一个类在Unix下可以工作,但是Windows下却不行(反之亦然)
* Invalid filenames due to double or missing path separators
由于两个或缺少分隔符而产生的 非法文件名错误。
* UNC filenames (on Windows) don't work with my home-grown filename utility function
Windows下的UNC文件名在我们自己写的文件名工具函数中不起作用。
* etc. etc.
等等。
These are good reasons not to work with filenames as Strings. Using java.io.File instead handles many of the above cases
nicely. Thus, our best practice recommendation is to use java.io.File instead of String for filenames to avoid platform
dependencies.
String作为文件名很容易出错。转而使用java.io.File就可以很好的避免上面的现象。因此,我们的最佳实践的建议是使用java.io.File而非
String作为文件名,来避免操作系统的依赖。
Version 1.1 of commons-io now includes a dedicated filename handling class - FilenameUtils . This does handle many of these
filename issues, however we still recommend, wherever possible, that you use java.io.File objects.
commons-io的1.1版本已经包含了专门的类:FilenameUtils。尽管它可以处理很多文件名问题,但是我们仍然建议您,无论如何最好使用
java.io.File。
Let's look at an example.
我们来看一个例子:
public static String getExtension(String filename) {
int index = filename.lastIndexOf('.');
if (index == -1) {
return "";
} else {
return filename.substring(index + 1);
}
}
Easy enough? Right, but what happens if someone passes in a full path instead of only a filename? Consider the following,
perfectly legal path: "C:\Temp\documentation.new\README". The method as defined above would return "new\README" - definitely
not what you wanted.
非常易懂吧?好,请问如果某人使用文件的完全路径而不仅仅是文件名作为参数,来调用这个方法时,会发生什么?比如下面这个,相当合法
的路径:"C:\Temp\documentation.new\README"。 按照上面的方法,会返回"new\README" - 这个结果不是我们想要的。
Please use java.io.File for filenames instead of Strings. The functionality that the class provides is well tested. In
FileUtils you will find other useful utility functions around java.io.File.
处理文件名时,请一定使用java.io.File而不是String. 前者提供的函数经过了相当全面的测试。在FileUtils你会发现与java.io.File相关
的其他有用的函数。
Instead of:
请不要这样写:
String tmpdir = "/var/tmp";
String tmpfile = tmpdir + System.getProperty("file.separator") + "test.tmp";
InputStream in = new java.io.FileInputStream(tmpfile);
...write:
而应该这样写:
File tmpdir = new File("/var/tmp");
File tmpfile = new File(tmpdir, "test.tmp");
InputStream in = new java.io.FileInputStream(tmpfile);
Buffering streams
IO performance depends a lot from the buffering strategy. Usually, it's quite fast to read packets with the size of 512 or
1024 bytes because these sizes match well with the packet sizes used on harddisks in file systems or file system caches. But
as soon as you have to read only a few bytes and that many times performance drops significantly.
IO的性能很大程度上取决于缓冲的策略。通常说来,每次使用512或1024字节来读一个包会非常快,因为这些字节的大小与文件系统的硬盘或
者缓存是同样大的。但是如果我们不得不每次只读一点点,却又要读很多次的话,性能就下降的很明显。
Make sure you're properly buffering streams when reading or writing streams, especially when working with files. Just
decorate your FileInputStream with a BufferedInputStream:
请确保你在读写流时使用合适的缓冲,特别是在处理文件的时候。简单的使用BufferedInputStream来修饰FileInputStream:
InputStream in = new java.io.FileInputStream(myfile);
try {
in = new java.io.BufferedInputStream(in);

in.read(.....
} finally {
IOUtils.closeQuietly(in);
}
Pay attention that you're not buffering an already buffered stream. Some components like XML parsers may do their own
buffering so decorating the InputStream you pass to the XML parser does nothing but slowing down your code. If you use our
CopyUtils or IOUtils you don't need to additionally buffer the streams you use as the code in there already buffers the copy
process. Always check the Javadocs for information. Another case where buffering is unnecessary is when you write to a
ByteArrayOutputStream since you're writing to memory only.
请注意,不要对已经被缓冲处理过的流再次缓冲。比如XML parser的一些组件自己会进行缓冲处理,所以我们在这之前进行缓冲操作是多余的
,只能降低程序的运行速度。如果你使用了CopyUtils或 IOUtils包你就不需要对某个stream进行缓冲,因为在COPY的过程中就已经实现了缓
冲。没事儿多看看javadoc吧(这句话翻译的最有感觉,哈哈)。缓冲的另一个不必要的情况是对ByteArrayOutputStream使用,因为它只是写
入到内存中。

Back