快捷搜索:  汽车  科技

apache 新版教程(程序员的福音-)

apache 新版教程(程序员的福音-)IOUtils01Commons IO目前最新版本是2.10.0,最低要求Java8以上。包结构如下:org.apache.commons.io org.apache.commons.io.comparator org.apache.commons.io.file org.apache.commons.io.filefilter org.apache.commons.io.function org.apache.commons.io.input org.apache.commons.io.monitor org.apache.commons.io.output org.apache.commons.io.serialization下面只列举其中常用的加以说明,其余感兴趣的可以自行翻阅源码研究。

此文是系列文章第三篇,前几篇请点击链接查看

程序猿的福音 - Apache Commons简介

程序员的福音 - Apache Commons Lang

Apache Commons IO是对java.io的扩展,主要是对Java中的bio封装了一些好用的工具类,nio涉及的较少,关于bio和nio问题我们后续再聊。

Commons IO目前最新版本是2.10.0,最低要求Java8以上。

包结构如下:

org.apache.commons.io org.apache.commons.io.comparator org.apache.commons.io.file org.apache.commons.io.filefilter org.apache.commons.io.function org.apache.commons.io.input org.apache.commons.io.monitor org.apache.commons.io.output org.apache.commons.io.serialization

apache 新版教程(程序员的福音-)(1)

下面只列举其中常用的加以说明,其余感兴趣的可以自行翻阅源码研究。

01

IOUtils

IOUtils可以说是Commons IO中最常用的了,下面直接看例子。

1. 关闭流

InputStream inputStream = new FileinputStream("test.txt"); OutputStream outputStream=newFileoutputStream("test.txt"); //原生写法 if(inputStream!=null){ try{ inputStream.close(); }catch(IOExceptione){ e.printStackTrace(); } } if(outputStream!=null){ try{ outputStream.close(); }catch(IOExceptione){ e.printStackTrace(); } } //commons写法(可以传任意数量的流) IOUtils.closeQuietly(inputStream outputStream);

2. 读取流

//==== 输入流转换为byte数组 ==== //原生写法 InputStream is = new FileInputStream("foo.txt"); byte[] buf = new byte[1024]; int len; ByteArrayOutputStreamout=newByteArrayOutputStream(); while((len=is.read(buf))!=-1){ out.write(buf 0 len); } byte[]result=out.toByteArray(); //commons写法 byte[]result2=IOUtils.toByteArray(is); // --------------------------------------- // ==== 输入流转换为字符串 ==== // 原生写法 InputStreamis=newFileInputStream("foo.txt"); BufferedReader br = new BufferedReader(new InputStreamReader(is "UTF-8")); StringBuilder sb = new StringBuilder(); String line; while ((line = br.readLine()) != null) { sb.append(line); } String result = sb.toString(); // commons写法 String result2 = IOUtils.toString(is "UTF-8"); // IOUtils.toString 还有很多重载方法,保证有你想要的 // 将reader转换为字符串 StringtoString(Readerreader StringCharset)throwsIOException; //将url转换为字符串,也就是可以直接将网络上的内容下载为字符串 String toString(URL url String charset) throws IOException;

3. 其他

//按照行读取结果 InputStream is = new FileInputStream("test.txt"); List<String> lines = IOUtils.readLines(is "UTF-8"); // 将行集合写入输出流 OutputStream os = new FileOutputStream("newTest.txt"); IOUtils.writeLines(lines System.lineSeparator() os "UTF-8"); // 拷贝输入流到输出流 InputStreaminputStream=newFileInputStream("src.txt"); OutputStream outputStream = new FileOutputStream("dest.txt"); IOUtils.copy(inputStream outputStream);

02

文件相关

文件相关主要有FileUtils:文件工具类,FilenameUtils:文件名工具类,PathUtils:路径工具类(主要是操作JDK7新增的java.nio.file.Path类)

1. 文件读写

FilereadFile=newFile("test.txt"); // 读取文件 String str = FileUtils.readFileToString(readFile "UTF-8"); // 读取文件为字节数组 byte[] bytes = FileUtils.readFileToByteArray(readFile); // 按行读取文件 List<String> lines = FileUtils.readLines(readFile "UTF-8"); File writeFile = new File("out.txt"); // 将字符串写入文件 FileUtils.writeStringToFile(writeFile "测试文本" "UTF-8"); // 将字节数组写入文件 FileUtils.writeByteArrayToFile(writeFile bytes); // 将字符串列表一行一行写入文件 FileUtils.writeLines(writeFile lines "UTF-8");

2. 移动和复制

FilesrcFile=newFile("src.txt"); File destFile = new File("dest.txt"); File srcDir = new File("/srcDir"); File destDir = new File("/destDir"); // 移动/拷贝文件 FileUtils.moveFile(srcFile destFile); FileUtils.copyFile(srcFile destFile); // 移动/拷贝文件到目录 FileUtils.moveFileToDirectory(srcFile destDir true); FileUtils.copyFileToDirectory(srcFile destDir); // 移动/拷贝目录 FileUtils.moveDirectory(srcDir destDir); FileUtils.copyDirectory(srcDir destDir); // 拷贝网络资源到文件 FileUtils.copyURLToFile(new URL("http://xx") destFile); // 拷贝流到文件 FileUtils.copyInputStreamToFile(new FileInputStream("test.txt") destFile); // ... ...

3. 其他文件操作

File file = new File("test.txt"); File dir = new File("/test"); // 删除文件 FileUtils.delete(file); // 删除目录 FileUtils.deleteDirectory(dir); // 文件大小,如果是目录则递归计算总大小 long s = FileUtils.sizeOf(file); // 则递归计算目录总大小,参数不是目录会抛出异常 long sd = FileUtils.sizeOfDirectory(dir); // 递归获取目录下的所有文件 Collection<File> files = FileUtils.listFiles(dir null true); // 获取jvm中的io临时目录 FileUtils.getTempDirectory(); // ... ...

4. 文件名称相关

// 获取名称,后缀等 String name = "/home/xxx/test.txt"; FilenameUtils.getName(name); // "test.txt" FilenameUtils.getBaseName(name); // "test" FilenameUtils.getExtension(name); // "txt" FilenameUtils.getPath(name); // "/home/xxx/" // 将相对路径转换为绝对路径 FilenameUtils.normalize("/foo/bar/.."); // "/foo"

5. JDK7的Path操作

// path既可以表示目录也可以表示文件 // 获取当前路径 Path path = PathUtils.current(); // 删除path PathUtils.delete(path); // 路径或文件是否为空 PathUtils.isEmpty(path); // 设置只读 PathUtils.setReadOnly(path true); // 复制 PathUtils.copyFileToDirectory(Paths.get("test.txt") path); PathUtils.copyDirectory(Paths.get("/srcPath") Paths.get("/destPath")); // 统计目录内文件数量 Counters.PathCounters counters = PathUtils.countDirectory(path); counters.getByteCounter(); // 字节大小 counters.getDirectoryCounter(); // 目录个数 counters.getFileCounter(); // 文件个数 // ... ...

03

流相关

org.apache.commons.io.input和org.apache.commons.io.output包下有许多好用的过滤流,下面列举几个做下说明

1. 自动关闭的输入流 AutoCloseInputStream

/** *AutoCloseInputStream是一个过滤流,用来包装其他流,读取完后流会自动关掉 *实现原理很简单,当读取完后将底层的流关闭,然后创建一个ClosedInputStream赋值给它包装的输入流。 *注:如果输入流没有全部读取是不会关掉底层流的 */ publicvoidautoCloseDemo()throwsException{ InputStreamis=newFileInputStream("test.txt"); AutoCloseInputStreamacis=newAutoCloseInputStream(is); IOUtils.toByteArray(acis);//将流全部读完 //可以省略关闭流的逻辑了 }

2. 倒序文件读取 ReversedLinesFileReader

//从后向前按行读取 try(ReversedLinesFileReaderreader=newReversedLinesFileReader(newFile("test.txt") Charset.forName("UTF-8"))){ StringlastLine=reader.readLine();//读取最后一行 List<String>line5=reader.readLines(5);//从后再读5行 }

3. 带计数功能的流 CountingInputStream,CountingOutputStream

/** *大家都知道只给一个输入流咱们是没办法准确的知道它的大小的,虽说流提供了available()方法 *但是这个方法只有在ByteArrayInputStream的情况下拿到的是准确的大小,其他如文件流网络流等都是不准确的 *(当然用野路子也可以实现,比如写入临时文件通过File.length()方法获取,然后在将文件转换为文件流) *下面这个流可以实现计数功能,当把文件读完大小也就计算出来了 */ publicvoidcountingDemo(){ InputStream is = new FileInputStream("test.txt"); try(CountingInputStreamcis=newCountingInputStream(is)){ Stringtxt=IOUtils.toString(cis "UTF-8"); //文件内容 longsize=cis.getByteCount(); //读取的字节数 }catch(IOExceptione){ //异常处理 } }

4. 可观察的输入流 ObservableInputStream

可观察的输入流(典型的观察者模式),可实现边读取边处理

比如将某些字节替换为另一个字节,计算md5摘要等

当然你也可以完全写到文件后在做处理,这样相当于做了两次遍历,性能较差。

这是一个基类,使用时需要继承它来扩展自己的流,示例如下:

private class MyObservableInputStream extends ObservableInputStream { class MyObserver extends Observer { @Override public void data(final int input) throws IOException { // 做自定义处理 } @Override public void data(final byte[] input final int offset final int length) throws IOException { // 做自定义处理 } } public MyObservableInputStream(InputStream inputStream) { super(inputStream); } }

5. 其他

BOMInputStream: 同时读取文本文件的bom头

BoundedInputStream:有界的流,控制只允许读取前x个字节

BrokenInputStream: 一个错误流,永远抛出IOException

CharSequenceInputStream: 支持StringBuilder StringBuffer等读取

LockableFileWriter: 带锁的Writer,同一个文件同时只允许一个流写入,多余的写入操作会跑出IOException

StringBuilderWriter: StringBuilder的Writer

... ...

04

文件比较器

org.apache.commons.io.compare包有很多现成的文件比较器,可以对文件排序的时候直接拿来用。

DefaultFileComparator:默认文件比较器,直接使用File的compare方法。(文件集合排序( Collections.sort() )时传此比较器和不传效果一样)

DirectoryFileComparator:目录排在文件之前

ExtensionFileComparator:扩展名比较器,按照文件的扩展名的ascii顺序排序,无扩展名的始终排在前面

LastModifiedFileComparator:按照文件的最后修改时间排序

NameFileComparator:按照文件名称排序

PathFileComparator:按照路径排序,父目录优先排在前面

SizeFileComparator:按照文件大小排序,小文件排在前面(目录会计算其总大小)

CompositeFileComparator:组合排序,将以上排序规则组合在一起

使用示例如下:

List<File> files = Arrays.asList(new File[]{ new File("/foo/def") new File("/foo/test.txt") new File("/foo/abc") new File("/foo/hh.txt")}); // 排序目录在前 Collections.sort(files DirectoryFileComparator.DIRECTORY_COMPARATOR); // ["/foo/def" "/foo/abc" "/foo/test.txt" "/foo/hh.txt"] // 排序目录在后 Collections.sort(files DirectoryFileComparator.DIRECTORY_REVERSE); // ["/foo/test.txt" "/foo/hh.txt" "/foo/def" "/foo/abc"] // 组合排序,首先按目录在前排序,其次再按照名称排序 Comparator dirAndNameComp = new CompositeFileComparator( DirectoryFileComparator.DIRECTORY_COMPARATOR NameFileComparator.NAME_COMPARATOR); Collections.sort(files dirAndNameComp); // ["/foo/abc" "/foo/def" "/foo/hh.txt" "/foo/test.txt"]

05

文件监视器

org.apache.commons.io.monitor包主要提供对文件的创建、修改、删除的监听操作,下面直接看简单示例。

publicstaticvoidmain(String[] args)throwsException{ // 监听目录下文件变化。可通过参数控制监听某些文件,默认监听目录所有文件 FileAlterationObserver observer = new FileAlterationObserver("/foo"); observer.addListener(new myListener()); FileAlterationMonitor monitor = new FileAlterationMonitor(); monitor.addObserver(observer); monitor.start(); // 启动监视器 Thread.currentThread().join(); // 避免主线程退出造成监视器退出 } privateclassmyListenerextendsFileAlterationListenerAdaptor{ @Override public void onFileCreate(File file) { System.out.println("fileCreated:" file.getAbsolutePath()); } @Override public void onFileChange(File file) { System.out.println("fileChanged:" file.getAbsolutePath()); } @Override public void onFileDelete(File file) { System.out.println("fileDeleted:" file.getAbsolutePath()); } }

06

总结

除了以上介绍的工具类外,还有其他不是很常用的就不多做介绍了。感兴趣的可以自行翻阅源码研究。

后续章节我将继续给大家介绍commons中其他好用的工具类库,期待你的关注。

猜您喜欢: