apache commons学习系列记录之IO组件version2.4之一
来源:互联网 发布:知乎 let it go 编辑:程序博客网 时间:2024/05/23 23:25
基于commons-IO-2.4版本
一、org.apache.commons.io
IOUtils
简化InputStream,OutputStream,Writer,Reader等的IO操作
内部自动缓存buffer,友好的关闭流closeQuetly,以LineIterator行迭代器的形式读取文件,流,File与流,String的转换。直接从流到String的转换
跳过读取等。
DirectoryWalker:
DirectoryWolker<T>抽象类,用于层次遍历目录及子目录。同时给它的子类提供hooks钩子方法以便处理相关事件行为。这些钩子方法以handle开头,由DirecotryWalker抽象类的机制去调用,实现者无需关心。
一般与IO组件的FileFilter结合使用,可以指定遍历深度。这些FIleFilter实现位于IO组件的filefilter包中。
由于遍历过程比较耗时,所以这个遍历过程还提供取消功能。
FileUtils:
包含处理文件与目录的操作,如移动,复制,读取,写入,比较,复制,大小,遍历,删除,生成文件校验码等。
FilenameUtils:便于路径的一致性
SystemUtils:获取卷的剩余容量
LineIterator:行迭代器。一般用于迭代从文件或流中读取的数据。
1.IOUtils:
closeQuietly - these methods close a stream ignoring nulls and exceptions
toXxx/read - these methods read data from a stream
write - these methods write data to a stream
copy - these methods copy all the data from one stream to another
contentEquals - these methods compare the content of two streams
有用的Field: DIR_SEPARATOR,LINE_SEPARATORstatic void closeQuietly(Closeable closeable)用于安静地关闭流stream,reader,writer或socket。
copy方法 可以将数据直接从一个流copy到另外一个流,同时还可以指定字符编码。但是需要注意的是这些数据都会直接通过内存,所以在copy大文件的时候需要特别注意这一点。
copy(Reader input, OutputStream output, Charset/String encoding)
Copy chars from aReaderto bytes on anOutputStreamusing the specified character encoding, and
calling flush.
copy大文件可以是用copyLarge方法,它可以指定缓存char[],byte[]的大小,指定拷贝的范围,长度等。
copyLarge(InputStream input, OutputStream output,
byte[] buffer)
以行为单位迭代读取数据:数据来源-流,举例:
static LineIterator lineIterator(InputStream input, String encoding)会得到LineIterator迭代器来进行迭代,
不过最后要记得手动关闭这个迭代器以释放资源。
LineIterator it = IOUtils.lineIterator(stream, charset);while (it.hasNext()) { String line = it.nextLine(); /// do something with line}} finally {IOUtils.closeQuietly(stream);}以行为单位读取得带列表而非迭代器。readLines方法可以得到行列表。
跳过读取:skip.
skip(Reader input,long toSkip)
写入write:类似
write(byte[]/char[]/String/Collection, Writer/OutputStream)可以指定编码,以及行结尾符。
与其他流或者形式的转换:
toBufferedInputStream, toByteArray, toCharArray, toInputStream, toString
IOUtils使用举例:传统方式:InputStream in = new URL( "http://commons.apache.org" ).openStream();try { InputStreamReader inR = new InputStreamReader( in ); BufferedReader buf = new BufferedReader( inR ); String line; while ( ( line = buf.readLine() ) != null ) { System.out.println( line ); }} finally { in.close();}使用IOUtils方式:InputStream in = new URL( "http://commons.apache.org" ).openStream();try { System.out.println( IOUtils.toString( in ) );} finally { IOUtils.closeQuietly(in);}从上面可以看到使用IOUtils的优势了。
2. DirectoryWalker<T>抽象类
public class FileCleaner extends DirectoryWalker { public FileCleaner() { super(); } public List clean(File startDirectory) { List results = new ArrayList(); walk(startDirectory, results);// startDirecotry代表要遍历的目录,results代表想要保存的结果集。 return results; } protected boolean handleDirectory(File directory, int depth, Collection results) { // delete svn directories and then skip if (".svn".equals(directory.getName())) { directory.delete(); return false; } else { return true; } } protected void handleFile(File file, int depth, Collection results) { // delete file and add to list of deleted file.delete(); results.add(file); } }
选择哪些目录和文件来进行处理对于WalkDirectory来说很重要。我们可以通过三种方式来确定。
第一种遍历所有那么就无需使用FileFilter
第二种指定针对目录和文件的单个Filter。这个Filter对于所有文件和目录都起作用。
第三种方式为分别为目录和文件制定各自的FileFilter.推荐。
第二种public class FooDirectoryWalker extends DirectoryWalker { public FooDirectoryWalker(FileFilter filter) { super(filter, -1);//其中-1的位置代表深度,如果<0则代表没有限制。 } }示例:创建一个FileFilter:创建一个过滤隐藏目录的Filter// Build up the filters and create the walker // Create a filter for Non-hidden directories IOFileFilter fooDirFilter = FileFilterUtils.andFileFilter(FileFilterUtils.directoryFileFilter, HiddenFileFilter.VISIBLE);创建一个过滤.txt结尾文件的FIlter// Create a filter for Files ending in ".txt" IOFileFilter fooFileFilter = FileFilterUtils.andFileFilter(FileFilterUtils.fileFileFilter, FileFilterUtils.suffixFileFilter(".txt"));组合者两个Filter为一个FIlter // Combine the directory and file filters using an OR condition java.io.FileFilter fooFilter = FileFilterUtils.orFileFilter(fooDirFilter, fooFileFilter);使用这个组合FileFilter来构造WalkDirectory // Use the filter to construct a DirectoryWalker implementation FooDirectoryWalker walker = new FooDirectoryWalker(fooFilter);第三种方式为分别为目录和文件制定各自的FileFilter.推荐。For example, if you wanted all directories which are not hidden and files which end in ".txt": public class FooDirectoryWalker extends DirectoryWalker { public FooDirectoryWalker(IOFileFilter dirFilter, IOFileFilter fileFilter) { super(dirFilter, fileFilter, -1); } } // Use the filters to construct the walker FooDirectoryWalker walker = new FooDirectoryWalker( HiddenFileFilter.VISIBLE, FileFilterUtils.suffixFileFilter(".txt"), );
可取消的遍历进程(Cancellation):由于遍历需要耗时,我们需要定义其为可以取消的。子类必须实现这一点。
原理为:
在子类内部抛出DirectoryWalker.CancelException,这个异常会被walk()方法所捕获,然后walk()方法会触发调用handleCancelled()来处理取消任务,这个方法供子类定制。控制子类在内部抛出DirectoryWalker.CancelException异常的方式有两种:
一中是外部/多线程方式。不过需要配和覆盖
一中是内部直接抛出DirectoryWalker.CancelException。
protected boolean handleIsCancelled(File file, int depth, Collection<T> results)
方法,这个方法返回true则它会抛出异常告诉walk()方法来终止遍历。
对外则提供一个用于控制这个返回值标志的方法cancel()以公共外届调用。。
public class FooDirectoryWalker extends DirectoryWalker { private volatile boolean cancelled = false;//注意多线程环境下flag的线程安全性,此处设置为volatile,但是要注意者也不是很安全,但对于目前足够了。 public void cancel() { //对外提供cancel方法用于设置flag, cancelled = true; } protected boolean handleIsCancelled(File file, int depth, Collection results) { //关键需要覆盖这个方法,返回值确定是否立即stop这个任务。 return cancelled; } protected void handleCancelled(File startDirectory, Collection results, CancelException cancel) {//这是确定停止后最后调用的用于处理停止的方法。。 // implement processing required when a cancellation occurs } }
内部方式示例:通过在内部抛出DirectoryWalker.CancelException控制终止,这个Exception会被walk()方法捕获。
public class BarDirectoryWalker extends DirectoryWalker { protected boolean handleDirectory(File directory, int depth, Collection results) throws IOException { // cancel if hidden directory if (directory.isHidden()) { throw new CancelException(file, depth); } return true; } protected void handleFile(File file, int depth, Collection results) throws IOException { // cancel if read-only file if (!file.canWrite()) { throw new CancelException(file, depth); } results.add(file); } protected void handleCancelled(File startDirectory, Collection results, CancelException cancel) { // implement processing required when a cancellation occurs } }
3.FileUtils:包含处理文件与目录的操作,如移动,复制,读取,写入,比较,复制,大小,遍历,删除,生成文件校验码等。
示例;读取文件以行的形式为列表、
File file = new File("/commons/io/project.properties");
List lines = FileUtils.readLines(file, "UTF-8");
将文件大小以易读的形式转换方法:
static String byteCountToDisplaySize(BigInteger/long size)
如1024000:变成“1M”
生成文件的校验码:配合使用java.util.zip.Checksum接口和java.util.zip.CRC32/Adler32算法。
checksum(File file, Checksum checksum)
checksumCRC32(File file)
复制目录:移动,通过FileFilter过滤copyDirectory(File srcDir, File destDir, [FileFilter filter])
复制文件:移动,到输出流,到目录copyFile(File input, OutputStream output)
copyFile(File srcFile, File destFile)
copyFileToDirectory(File srcFile, File destDir)
删除文件和目录deleteDirectory(File directory)
deleteQuietly(File file)
检查目录是否包含某个文件:directoryContains(File directory, File child)
创建File对象:getFile([File directory], String... names)
获取系统临时目录和用户目录路径:getTempDirectory[Path]()
getUserDirectory[Path]()
遍历目录:Iterator<File> iterateFiles(File directory, IOFileFilter fileFilter, IOFileFilter dirFilter)最后的Filter参数决定是否递归遍历
使用TrueFileFilter.TRUE作为第二个filter则可以递归遍历。
文件的读取:获取LineIterator:lineIterator(File file)还可以指定编码
还有移动方法move一系列
还有读取文件为不同的形式:
readFileToByteArray/String ; readLines;
还有将不同形式的数据写入到文件。
文件与目录大小
sizeOf(File f); sizeOfDirectory;
4.FilenameUtils:便于在各种平台间移植的操作工具。
对文件路径的操作。String filename = "C:/commons/io/../lang/project.xml";
String normalized = FilenameUtils.normalize(filename);
// result is "C:/commons/lang/project.xml"
含义:
the prefix - C:\
the path - dev\project\
the full path - C:\dev\project\
the name - file.txt
the base name - file
the extension - txt
6.FileSystemUtils取得卷或分区的剩余大小
FileSystemUtils.freeSpaceKb("C:"); // Windows
FileSystemUtils.freeSpaceKb("/volume"); // *nix
7.LineIterator:
An Iterator over the lines in aReader. 注意对其关闭以释放资源。
LineIterator it = FileUtils.lineIterator(file, "UTF-8");try { while (it.hasNext()) { String line = it.nextLine(); /// do something with line }} finally { LineIterator.closeQuietly(iterator);}
本人博客小站原文:
- apache commons学习系列记录之IO组件version2.4之一
- apache commons学习系列记录之IO组件version2.4之二
- apache commons组件学习系列记录之lang3
- apache commons学习系列之Email组件
- apache-comnons系列之commons-io-2.5 org.apache.commons.io.IOUtils学习笔记
- apache-comnons系列之commons-io-2.5 org.apache.commons.io.FileUtils学习笔记
- apache commons组件学习系列之configuration库
- apache commons组件学习之FileUpload
- apache-comnons系列之commons-pool2.4 学习笔记
- apache-comnons系列之commons-email1.4 学习笔记
- apache-comnons系列之commons-cli1.4 学习笔记
- apache.commons.io学习笔记
- Apache commons-io LineIterator学习
- Apache Commons IO组件介绍使用
- Apache Commons IO组件介绍使用
- Java-IO之Apache Commons IO(1)
- Java-IO之Apache Commons IO(2)
- apache-comnons系列之commons-collections4 org.apache.commons.collections4.CollectionUtils学习笔记
- jQuery get content between <div> tags
- 星期天怎么没人啊
- sencha touch实例:微博设置界面
- apache commons组件学习之FileUpload
- ASP.NET AJAX(开发代号Atlas)重要参考资源大收集
- apache commons学习系列记录之IO组件version2.4之一
- matlab 2010a linux 安装过程
- avsubtitleWriter demo解析(三):SubtitlesTextReader
- ASP.NET 服务器控件对应HTML标签
- apache commons学习系列记录之IO组件version2.4之二
- 如何处理海量数据(转)
- Openstack压力测试(二) -- 结果还不错!
- apache commons组件学习系列记录之lang3
- 博客发外链的注意事项