IO和NIO的性能差异及示例

3

我对Java NIO非常陌生,没有实际操作经验。关于Java NIO,我所知道的是它比java.IO更快。

因此,为了尝试一下,我考虑编写简单的程序,用于“将一个文件的内容复制到另一个文件”和“从大文件中搜索一个单词”。使用了Java.IO和Java.NIO包。

此外,我在操作开始和结束前后分别打印时间。

我发现NIO并没有更快的差异。可能我走错方向了。

请问有人能够指导我如何通过示例正确地看到差异吗?

编辑:

我真的很惊讶这个问题会得到负面评价。 我已经提到过我对NIO很陌生,并请指导我是否走错方向。 我没有发布程序,因为它只是一个基本的读写操作...请参见下面我用来测试的程序....

使用IO

public static void copyFile(File in, File out) throws Exception {

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    Date now = new Date();
    String strDate = sdf.format(now);

    System.out.println("Before Read :"+strDate);


    FileInputStream fis  = new FileInputStream(in);
    FileOutputStream fos = new FileOutputStream(out);
    try {
        byte[] buf = new byte[1024];
        int i = 0;
        while ((i = fis.read(buf)) != -1) {
            fos.write(buf, 0, i);
        }
    } 
    catch (Exception e) {
        throw e;
    }
    finally {
        if (fis != null) fis.close();
        if (fos != null) fos.close();
    }

    Date now1 = new Date();
    String strDate1 = sdf.format(now1);

    System.out.println("After Read :"+strDate1);


}

使用NIO
 public static void copyFile(File in, File out) 
        throws IOException 
{

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    Date now = new Date();
    String strDate = sdf.format(now);

    System.out.println("Before Read :"+strDate);

    FileChannel inChannel = new
        FileInputStream(in).getChannel();
    FileChannel outChannel = new
        FileOutputStream(out).getChannel();
    try {
        inChannel.transferTo(0, inChannel.size(),
                outChannel);
    } 
    catch (IOException e) {
        throw e;
    }
    finally {
        if (inChannel != null) inChannel.close();
        if (outChannel != null) outChannel.close();
    }

    Date now1 = new Date();
    String strDate1 = sdf.format(now1);

    System.out.println("After Read :"+strDate1);
}

我要把一个20MB的文件从一个文件复制到另一个文件。


为什么不展示你用于比较的代码呢?也许有一个错误导致了NIO版本的减速。 - Andrew Thompson
你应该使用比1024更大的缓冲区。现在磁盘簇大小至少为4096,你不应该低于这个值。而且你必须在循环中调用transferTo()方法;不能保证一次调用就能完成。 - user207421
2个回答

5
NIO允许您仅使用一个(或更少)线程来管理多个通道,但代价是与使用标准IO从阻塞流读取数据时相比,解析数据可能会更加复杂。如果您需要同时管理数千个仅发送少量数据的打开连接(例如聊天服务器),则在NIO中实现服务器可能是一个优势。同样,如果您需要保持许多与其他计算机的打开连接,例如在P2P网络中,则使用单个线程管理所有出站连接可能是一个优势。如果您有较少的高带宽连接,每次发送大量数据,则应选择标准IO服务器实现。Ref: 标准IO和NIO之间的区别


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接