经过测试没有发现IO与NIO的效率有很大的差别啊?各位帮忙分析一下

@Test
    public void testRWbyIO() throws IOException {
        FileInputStream fins= null;
        FileOutputStream fouts = null;
        try {
        
            File f = new File("D:/httpTestData/client/io/javadoc.rar");
            fins = new FileInputStream(f);
            
            File outF = new File("D:/httpTestData/client/io/javadoc");
            fouts = new FileOutputStream(outF);
            
            byte[] bytes = new byte[1024*1024];
            while(fins.read(bytes)>0) {
                fouts.write(bytes);
            }
        }finally {
            if (fins != null) {
                fins.close();
            }
            if (fouts != null) {
                fouts.close();
            }
        }
    }
    
    @Test
    public void testRWbyNIO1() throws IOException {
        FileInputStream fins= null;
        FileOutputStream fouts = null;
        try {
        
            File f = new File("D:/httpTestData/client/nio/javadoc.rar");
            fins = new FileInputStream(f);
            FileChannel readChannel = fins.getChannel();
            
            File outF = new File("D:/httpTestData/client/nio/javadoc");
            fouts = new FileOutputStream(outF);
            FileChannel writeChannel = fouts.getChannel();
            
            ByteBuffer bb = ByteBuffer.allocate(1024*1024);
            
            while(true) {
                bb.clear();
                int i = readChannel.read(bb);
                if (i ==-1) {
                    break;
                }
                
                bb.flip();
                writeChannel.write(bb);
            }
        }finally {
            if (fins != null) {
                fins.close();
            }
            if (fouts != null) {
                fouts.close();
            }
        }
    }

 测试结果:

    <testcase name="testRWbyIO"  time="34.704"/>
    <testcase name="testRWbyNIO1"  time="33.61"/>

 两个方法处理的是同一个文件的两个拷贝,文件大小28M,最终结果两个时间差不多,缓存设置有点大,所以很慢

我想问什么情况之间IO和NIO有效率的差别呢? 难道主要是阻塞和非阻塞的使用?还是说我这个测试写得不好

[b]
NIO 与传统IO的测试,我也做过。两者在普通文件的读取时,速度几乎没有差异。

更有趣的是,如果传统IO,使用的得当(比如使用BufferedInputStream、BufferedReader
),是很快的。如果NIO使用不当(比如,我用MappedByteBuffer,将文件映射到内存,Buffer的大小是文件的总长度43M),速度是传统IO的二十分之一。[/b]

[b]引用IBM官方教程中的一句话,来解释:[/b]
[b][quote]在 JDK 1.4 中原来的 I/O 包和 NIO 已经很好地集成了。 java.io.* 已经以 NIO 为基础重新实现了,所以现在它可以利用 NIO 的一些特性。例如, java.io.* 包中的一些类包含以块的形式读写数据的方法,这使得即使在更面向流的系统中,处理速度也会更快。[/quote][/b]
[color=blue]
[b]可以看到,1.4后的IO经过了集成。所以NIO的好处,集中在其他特性上,而非速度了:

1、分散与聚集读取
2、文件锁定功能
3、网络异步IO[/b][/color]

NIO相对于IO的快是指在高并发情况下

NIO是为了解决web多线程时的线程占用问题的,不是说比IO快。

各位看官们我来谈谈我的看法,不对的地方请指正:
首先现在的io基本上都已经与nio集成,所以你这样测试根本没有差别
NIO与传统的标准IO之间的差别在于读写数据的方式,标准io是一个字节,一个字节的读取,而nio把这些交给通道,让操作系统去批量处理这些数据。把这些繁杂的数据交给操作系统来做。传统的io是没有缓冲的概念的,所以要想测试,
传统io
byte[] bytes = new byte[1024*1024];

while(fins.read(bytes)>0) {

fouts.write(bytes);

}

此处不应使用byte数组缓冲,而是模拟原始io方式一个一个字节读取,看两者读完所有数据的数据差。而以上这种方式,其实还是用了缓冲现在的io基本上都已经与nio集成,所以没差别
而造成这种差别来源:
1.一个字节一个字节的读取,每次read都会产生系统调用,会有状态切换,从用户态切换到内核态,然后一个一个字节的把内核缓冲区的数据搬运到用户态,这样的效率是低下的
2.而nio 则是切换一次,装载一批数据,就避免了状态的频繁切换。

其次nio还有诸多的其他方面的功能
例如:
1.Scatter/Gather 会是一个极其强大的工具。它允许您委托操作系统来完成辛苦
活:将读取到的数据分开存放到多个存储桶(bucket)或者将不同的数据区块合并成一个整体。这
是一个巨大的成就,因为操作系统已经被高度优化来完成此类工作了。它节省了您来回移动数据的66
工作,也就避免了缓冲区拷贝和减少了您需要编写、调试的代码数量。既然您基本上通过提供数据
容器引用来组合数据,那么按照不同的组合构建多个缓冲区阵列引用,各种数据区块就可以以不同
的方式来组合了
2.直接内存映射buffer,相当于直接在内存取数据,而不需要经过内核态的缓冲区
3,对于scoket编程,有非阻塞io的形式,支持io多路复用,改变了传统的一个线程只能管理一个链接,现在可以一个线程管理n个链接

写了一个测试比较案例:
@Test
public void channelTest00() {
try {
FileInputStream fis=new FileInputStream(new File("E:\input-file.txt"));
// RandomAccessFile file = new RandomAccessFile("E:\input-file.txt", "rw");
FileChannel channel = fis.getChannel();
ByteBuffer header = ByteBuffer.allocate(1024);
long date1=System.currentTimeMillis();
int count=channel.read(header);
while (count!=-1){
header.flip();
header.clear();
count=channel.read(header);
}
long date2=System.currentTimeMillis();
System.out.println(date2-date1);

        channel.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

@Test
public void inputOutStreamTest() {
    File file = new File("E:\\input-file.txt");
    try {
        FileInputStream fis = new FileInputStream(file);
        long date1=System.currentTimeMillis();
        int count = fis.read();
        while(count!=-1){
            count=fis.read();
        }
        long date2=System.currentTimeMillis();
        System.out.println(date2-date1);
       fis.close();
    } catch (FileNotFoundException e) {

    } catch (IOException e) {

    }
}