Apache commons io 效率之尝试与瞎写

我们使用Apache commons io,主要是为了提升各种效率。比如开发的效率,读取文件的效率,输出的效率等。输入、输入效率上的提升,是这个工具安身立命的本钱,是本;而开发效率的提升,能够让我们开发、项目相关人员获取实在的效益,是叶。

我们先说叶,再说本,对或者错,都是我的一家之言,仅供参考。

●在input中,最值得关注的方法之一是AutoCloseInputStream

这个输入流是一个底层输入流的代理,它能够在数据源的内容被完全读取到输入流后,后者当用户调用close()方法时,立即关闭底层的输入流。释放底层的资源(例如文件的句柄)。这个类的好处就是避免我们在代码中忘记关闭底层的输入流而造成文件处于一直打开的状态。

我们知道对于某些文件,只允许由一个进程打开。如果我们使用后忘记关闭那么该文件将处于一直“打开”的状态,其它进程无法读写。例如下面的例子:

InputStream ins = new FileInputStream(newFile("D:\\ffm83\\ffm83.txt"));

里面的FileInputStream(FILE)在打开后不能被显式关闭,这将导致可能出现的问题。如果我们使用了AutoCloseInputStream,那么当数据读取完毕后,底层的输入流会被自动关闭,迅速地释放资源。

AutoCloseInputStream ins =newAutoCloseInputStream((new FileInputStream(newFile("D:\\ffm83\\ffm83.txt"))));

示例代码:

packagetest.ffm83.commons.io;

importjava.io.File;

importjava.io.FileInputStream;

importjava.io.FileWriter;

importjava.io.IOException;

importjava.io.Writer;

importorg.apache.commons.io.IOUtils;

importorg.apache.commons.io.input.AutoCloseInputStream;

importorg.apache.commons.lang.StringUtils;

/**

* commonsio 的一些简单基本用法

* @author范芳铭

*/

public classIOAutoCloseUsage {

publicstatic void main(String[] args)
throws
Exception {

getInputCopyToWrite();

}

/**

* 输入流复制到输出流,利用AutoCloseInputStream

* @author 范芳铭

*/

privatestatic void getInputCopyToWrite()
throws
Exception {

AutoCloseInputStreamins =new AutoCloseInputStream((new FileInputStream(newFile("D:\\ffm83\\ffm83.txt"))));

Writerwrite = new FileWriter("D:\\ffm83\\write.txt");

try{

IOUtils.copy(ins,write);

System.out.println(StringUtils.center("输入流复制到输出流成功",50, "-"));

}catch(IOException e){

System.out.println(StringUtils.center("输入流复制到输出流失败",50, "-"));

e.printStackTrace();

}

write.close();

//ins.close();

}

}

●在output中,最重要的方法是ByteArrayOutputStream,FileWriterWithEncoding,LockableFileWriter

ByteArrayOutputStream 方法提升了输入输出的效率;

FileWriterWithEncoding 提供了特殊功能简化了效率;

LockableFileWriter 提供了特殊的功能;

为了查看Apache提供的ByteArrayOutputStream是怎么提供效率的,我们写个程序来看看。为了让测试有一定的客观性,我们利用http://blog.csdn.net/ffm83/article/details/41848149博客的页面的源代码,保存到本地进行。这个页面的源代码保存的文件对应的就是D:\\ffm83\\ffmBlog.txt。

测试用代码如下:

packagetest.ffm83.commons.io;

importjava.io.ByteArrayOutputStream;

importjava.io.File;

importjava.io.FileInputStream;

importorg.apache.commons.io.input.AutoCloseInputStream;

importorg.apache.commons.lang.time.StopWatch;

/**

* commons io 的ByteArrayOutputStream方法和java自带的ByteArrayOutputStream效率比较。

* @author 范芳铭

*/

publicclass ByteArrayOutputStreamTest {

public final static int BUFFER_SIZE =4096;

public static void main(String[] args)throws Exception {

runTestApacheMethod(100000,"热身APACH方法");  //热身下

runTestApacheMethod(500000,"执行APACHE方法"); //正式开跑

runTestJavaMethod(100000,"热身JAVA自带"); //热身下

runTestJavaMethod(500000,"执行JAVA自带"); //正式开跑

}

/**

* 测试用的主运行方法

* @author 范芳铭

*/

private static voidrunTestJavaMethod(int iterations,String name) throws Exception{

StopWatch sw = newStopWatch();

sw.start();

for(int i = 0 ; i <iterations ;  i ++){

//在这里调用需要运行的方法

runJavaByteArrayOutputStream();

}

sw.stop();

System.out.println(name +",累计花费的时间:" + sw.getTime() );

}

private static voidrunTestApacheMethod(int iterations,String name) throws Exception{

StopWatch sw = newStopWatch();

sw.start();

for(int i = 0 ; i <iterations ;  i ++){

//在这里调用需要运行的方法

runApacheByteArrayOutputStream();

}

sw.stop();

System.out.println(name +",累计花费的时间:" + sw.getTime());

}

/**

* 看java自带的ByteArrayOutputStream效率

* @author 范芳铭

*/

private static voidrunJavaByteArrayOutputStream() throws Exception {

AutoCloseInputStream ins =newAutoCloseInputStream((new FileInputStream(

newFile("D:\\ffm83\\ffmBlog.txt"))));

ByteArrayOutputStreambouts=new ByteArrayOutputStream();

byte[] data = newbyte[BUFFER_SIZE];

int count = -1;

while((count =ins.read(data,0,BUFFER_SIZE)) != -1)

bouts.write(data, 0, count);

bouts.close();

}

/**

* 看java自带的ByteArrayOutputStream效率

* @author 范芳铭

*/

private static voidrunApacheByteArrayOutputStream() throws Exception {

AutoCloseInputStream ins =newAutoCloseInputStream((new FileInputStream(

newFile("D:\\ffm83\\ffm83.txt"))));

org.apache.commons.io.output.ByteArrayOutputStreambouts =

neworg.apache.commons.io.output.ByteArrayOutputStream();

byte[] data = newbyte[BUFFER_SIZE];

int count = -1;

while((count = ins.read(data,0,BUFFER_SIZE))!= -1)

bouts.write(data, 0, count);

bouts.close();

}

}

运行结果如下:

热身APACH方法,累计花费的时间:9184

执行APACHE方法,累计花费的时间:43893

热身JAVA自带,累计花费的时间:17144

执行JAVA自带,累计花费的时间:85052

时间效率提升不到50%,难道我眼镜戴错了吗?

不过蚊子腿再细也是肉,虽然提升不多,好歹也是进步。换个思路再试试吧。

/**

* 看java自带的ByteArrayOutputStream效率

* @author 范芳铭

*/

privatestatic void runJavaByteArrayOutputStream()
throwsException {

AutoCloseInputStreamins =new AutoCloseInputStream((new FileInputStream(

newFile("D:\\ffm83\\ffmBlog.txt"))));

ByteArrayOutputStreambouts=new ByteArrayOutputStream();

byte[]data = new byte[BUFFER_SIZE];

intcount = -1;

while((count= ins.read(data,0,BUFFER_SIZE)) != -1)

bouts.write(data, 0, count);

bouts.close();

}

这代码里有几个主要方法,一个是AutoCloseInputStream读取流文件,然后才是ByteArrayOutputStream,不知道是否是两个互相有影响,那么把这个方法移开试试看吧。

调整后的代码如下:

package test.ffm83.commons.io;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.FileInputStream;

importorg.apache.commons.io.input.AutoCloseInputStream;

import org.apache.commons.lang.time.StopWatch;

/**

* commonsio 的ByteArrayOutputStream方法和java自带的ByteArrayOutputStream效率比较。

* @author范芳铭

*/

public class ByteArrayOutputStreamTest {

publicfinal static int BUFFER_SIZE = 4096;

publicstatic void main(String[] args) throws Exception {

AutoCloseInputStreamins =new AutoCloseInputStream((new FileInputStream(

newFile("D:\\ffm83\\ffmBlog.txt"))));

runTestApacheMethod(100000,"热身APACH方法",ins);  //热身下

runTestApacheMethod(500000,"执行APACHE方法",ins);//正式开跑

runTestJavaMethod(100000,"热身JAVA自带",ins);//热身下

runTestJavaMethod(500000,"执行JAVA自带",ins);//正式开跑

}

/**

* 测试用的主运行方法

* @author 范芳铭

*/

privatestatic void runTestJavaMethod(int iterations,String name,

AutoCloseInputStreamins) throws Exception{

StopWatchsw = new StopWatch();

sw.start();

for(inti = 0 ; i < iterations ;  i ++){

//在这里调用需要运行的方法

runJavaByteArrayOutputStream(ins);

}

sw.stop();

System.out.println(name+ ",累计花费的时间:" + sw.getTime() );

}

privatestatic void runTestApacheMethod(int iterations,String name,

AutoCloseInputStreamins) throws Exception{

StopWatchsw = new StopWatch();

sw.start();

for(inti = 0 ; i < iterations ;  i ++){

//在这里调用需要运行的方法

runApacheByteArrayOutputStream(ins);

}

sw.stop();

System.out.println(name+ ",累计花费的时间:" + sw.getTime());

}

/**

* 看java自带的ByteArrayOutputStream效率

* @author 范芳铭

*/

privatestatic void runJavaByteArrayOutputStream(AutoCloseInputStream ins) throwsException {

ByteArrayOutputStreambouts=new ByteArrayOutputStream();

byte[]data = new byte[BUFFER_SIZE];

intcount = -1;

while((count= ins.read(data,0,BUFFER_SIZE)) != -1)

bouts.write(data, 0, count);

bouts.close();

}

/**

* 看apache的ByteArrayOutputStream效率

* @author 范芳铭

*/ privatestatic void runApacheByteArrayOutputStream(AutoCloseInputStream ins) throwsException {

org.apache.commons.io.output.ByteArrayOutputStreambouts =

neworg.apache.commons.io.output.ByteArrayOutputStream();

byte[]data = new byte[BUFFER_SIZE];

intcount = -1;

while((count= ins.read(data,0,BUFFER_SIZE)) != -1)

bouts.write(data, 0, count);

//bouts.write(ins);

bouts.close();

}

}

运行结果如下:

热身APACH方法,累计花费的时间:128

执行APACHE方法,累计花费的时间:530

热身JAVA自带,累计花费的时间:85

执行JAVA自带,累计花费的时间:434

这个,这个出人意料,apache commons 的方法居然比java原生态的居然要慢50%。查看apachecommons io中关于ByteArrayOutputStream的部分,相比于JDK自带的方法,这个类多了一个write(InputStream in)的方法。

把这段代码调整下:

privatestatic void runApacheByteArrayOutputStream(AutoCloseInputStreamins)
throws Exception {

org.apache.commons.io.output.ByteArrayOutputStreambouts =

neworg.apache.commons.io.output.ByteArrayOutputStream();

/*      byte[]data = new byte[BUFFER_SIZE];

intcount = -1;

while((count= ins.read(data,0,BUFFER_SIZE)) != -1)

bouts.write(data, 0, count); */

bouts.write(ins);

bouts.close();

}

运行结果如下:

热身APACH方法,累计花费的时间:43

执行APACHE方法,累计花费的时间:146

热身JAVA自带,累计花费的时间:82

执行JAVA自带,累计花费的时间:354

这一次,apache commons 的方法比java原生态的居然要快50%以上。使用新的类,那么就要尽量用它配套的方法,否则有可能得到错误甚至相反的结果。

我们这个应用,用到的方法很少,因此可以进一步研究:


ByteArrayOutputStream()

Creates a new byte array output stream.


ByteArrayOutputStream(int size)

Creates a new byte array output stream, with a buffer capacity of the specified size, in bytes.

有一个是有参数的,一个是没有参数的,我们刚才测试用的是没有参数的。我们在各种buff中可能有了解,如果把buff的值扩大,一般效率会提升的,试验是检验真理的最高标准,我们动手试一下。

代码做一下调整:

/**

* 看apache的ByteArrayOutputStream效率

* @author 范芳铭

*/

privatestatic void runApacheByteArrayOutputStream(AutoCloseInputStreamins)
throws Exception {

org.apache.commons.io.output.ByteArrayOutputStreambouts =

neworg.apache.commons.io.output.ByteArrayOutputStream(40960);

/*      byte[]data = new byte[BUFFER_SIZE];

intcount = -1;

while((count= ins.read(data,0,BUFFER_SIZE)) != -1)

bouts.write(data, 0, count); */

bouts.write(ins);

bouts.close();

}

运行结果如下:

热身APACH方法,size40960,累计花费的时间:668

执行APACHE方法,size40960,累计花费的时间:3702

热身JAVA自带,累计花费的时间:74

执行JAVA自带,累计花费的时间:379

代码继续调整下:

/**

* 看apache的ByteArrayOutputStream效率

* @author 范芳铭

*/

privatestatic void runApacheByteArrayOutputStream(AutoCloseInputStream ins)throws Exception {

org.apache.commons.io.output.ByteArrayOutputStreambouts =

neworg.apache.commons.io.output.ByteArrayOutputStream(4);

/*      byte[]data = new byte[BUFFER_SIZE];

intcount = -1;

while((count= ins.read(data,0,BUFFER_SIZE)) != -1)

bouts.write(data, 0, count); */

bouts.write(ins);

bouts.close();

}

运行结果如下:

热身APACH方法,size4,累计花费的时间:22

执行APACHE方法,size4,累计花费的时间:73

热身JAVA自带,累计花费的时间:79

执行JAVA自带,累计花费的时间:355

尝试了这么多,总结一下:

l   使用新的类,那么就要尽量用它配套的方法,否则有可能得到错误甚至相反的结果;

l   参数不要去想当然,要根据实际情况去调整,如果对效率有特殊要求,必要的测试是不可缺少的;

FileWriterWithEncoding

从这个类的名称已经可以很清楚的知道它的作用了。在JDK自带的FileWriter中,是无法设置encoding的,这个类允许我们采用默认或者指定的encoding,以字符的形式写到文件。为什么这个类可以改变字符嗯?

原理很简单:无非使用了OutputStreamWriter。而且这个类并不是继承与FileWriter,而是直接继承于Writer。

●LockableFileWriter

用“文件锁”而非“对象锁”来限制多线程环境下的写动作。这个类采用在JDK默认的系统临时目录下写文件:java.io.tmpdir属性。而且允许我们设置encoding。

如果多线程需要读写同一个文件,那么可以通过本方法对文件进行加锁操作。

时间: 2024-10-14 10:46:02

Apache commons io 效率之尝试与瞎写的相关文章

Apache Commons IO简介

虽然Google的guava对Java的IO操作进行了一定封装,但是它更偏向于集合.并发和缓存,在实际项目中,我非常喜欢guava,同时我也非常喜欢Apache的一个工具包org.apache.commons.io,这两个工具包提供非常强大的工具能力,能够简化代码逻辑,提高开发效率和质量,是每个Java程序员都应该掌握的工具包.此文简单介绍一下org.apache.commons.io,详细的可参考其API注,此文绝大部分内容翻译自http://www.javacodegeeks.com/201

Apache Commons IO入门教程(转)

Apache Commons IO是Apache基金会创建并维护的Java函数库.它提供了许多类使得开发者的常见任务变得简单,同时减少重复(boiler-plate)代码,这些代码可能遍布于每个独立的项目中,你却不得不重复的编写.这些类由经验丰富的开发者维护,对各种问题的边界条件考虑周到,并持续修复相关bug. 在下面的例子中,我们会向你演示一些不同功能的方法,这些功能都是在org.apache.commons.io包下.Apache Commons IO 是一个巨大工程,我们不会深入去剖析它的

maven:java.lang.NoClassDefFoundError: org/apache/commons/io/Charsets

今天从git上down了一个第三方jar ,这个jar里面用到了  String resultUrl = String.format(url,            URLEncoder.encode(ticket, Charsets.UTF_8.name())); 然而执行到这里的时候,就报错了: java.lang.NoClassDefFoundError: org/apache/commons/io/Charsets 第一反应就是jar包冲突了,看了下依赖,果然是有问题,如图所示: com

Caused by: java.lang.ClassNotFoundException: org.apache.commons.io.FileUtils

1.错误描述 警告: Could not create JarEntryRevision for [jar:file:/D:/MyEclipse/apache-tomcat-7.0.53/webapps/FirstSSH/WEB-INF/lib/struts2-core-2.3.16.3.jar]! java.lang.NoClassDefFoundError: org/apache/commons/io/FileUtils at com.opensymphony.xwork2.util.fs.

Tomcat中使用commons-io-2.5发生的错误java.lang.ClassNotFoundException: org.apache.commons.io.IOUtils

关键词:IntelliJ IDEA.Tomcat.commons-io-2.5.jar.java.lang.ClassNotFoundException: org.apache.commons.io.IOUtils 1.错误提示信息 图1 运行登录时错误信息 //Tomcat Localhost Log信息 org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [Servlet] in

java.lang.NoClassDefFoundError: org/apache/commons/io/output/DeferredFileOutputStream异常解决方法

使用Tomcat部署Servlet程序时,单步调试跟踪到: List<FileItem> itemList = sfu.parseRequest(request); 总是会报错:Java.lang.NoClassDefFoundError: org/apache/commons/io/output/DeferredFileOutputStream 直接运行后也是这个错误,解决方法: 添加引用包commons-io.jar到工程下,问题解决.有人说是commons-fileupload.jar包

apache commons io包基本功能

1. http://jackyrong.iteye.com/blog/2153812 2. http://www.javacodegeeks.com/2014/10/apache-commons-io-tutorial.html 3. http://www.importnew.com/13715.html 4. http://www.cnblogs.com/younggun/p/3247261.html (misybing:Apache Commons IO 包下载后,将该jar包添加到Ecli

Apache commons io 概要介绍

首先贴一段Apache commons IO官网上的概要介绍 Commons IO 2.4 API Packages org.apache.commons.io This package defines utility classes for working with streams, readers, writers and files. org.apache.commons.io.comparator This package provides various Comparator impl

java.lang.NoClassDefFoundError: org/apache/commons/io/output/DeferredFileOutputStream

java.lang.ClassNotFoundException: org.apache.commons.io.output.DeferredFileOutputStream at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1309) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(Webap