Java--Stream,NIO ByteBuffer,NIO MappedByteBuffer性能对比

目前Java中最IO有多种文件读取的方法,本文章对比Stream,NIO ByteBuffer,NIO MappedByteBuffer的性能,让我们知道到底怎么能写出性能高的文件读取代码。

package com.seeyon.nio;

import org.junit.Test;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/**
 * Created by yangyu on 16/12/28.
 */

/**
 * 比较Stream流,NIO ByteBuffer,NIO MappedByteBuffer性能对比
 * 其中Stream最慢,NIO MappedByteBuffer最快
 * Stream:1000ms
 * NIO ByteBuffer:220ms
 * NIO MappedByteBuffer:112ms
 */
public class Compare {

    /**
     * 使用stream作为IO流读取和写入文件
     * 速度:1000ms左右
     *
     * @throws IOException
     */
    @Test
    public void useStream() throws IOException {

        long startTime = System.currentTimeMillis();
        /**
         * 4000000个整数长度的文件
         */
        int num = 2000 * 2000;

        /**
         * 带缓冲的输出流,写文件
         */
        DataOutputStream dataOutputStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("/Users/yangyu/Downloads/compare.tmp")));
        for (int i = 0; i < num; i++) {
            dataOutputStream.writeInt(i);
        }
        dataOutputStream.close();

        int data = 0;
        /**
         * 带缓冲的输入流,读文件
         */
        DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream("/Users/yangyu/Downloads/compare.tmp")));
        try {
            while (true) {
                data = in.readInt();
            }
        } catch (EOFException e) {
            System.out.println("读取完成"+data);
        }
        in.close();
        long endTime = System.currentTimeMillis();
        System.out.println("ms:" + (endTime - startTime));
    }

    /**
     * 使用NIO ByteBuffer
     * 时间:220ms
     * @throws IOException
     */
    @Test
    public void useNioByteBuffer() throws IOException {
        long startTime = System.currentTimeMillis();
        int num = 2000*2000;
        /**
         * 文件输出流
         */
        FileOutputStream fileOutputStream = new FileOutputStream("/Users/yangyu/Downloads/compare.tmp");
        /**
         * NIO Channel 通道
         */
        FileChannel fileChannel = fileOutputStream.getChannel();
        /**
         * ByteBuffer缓冲区
         */
        ByteBuffer buffer = ByteBuffer.allocate(num*5);
        for (int i = 0; i < num; i++) {
            buffer.putInt(i);
        }
        /**
         * 为写做准备
         */
        buffer.flip();
        /**
         * 写操作
         */
        fileChannel.write(buffer);
        fileChannel.close();

        /**
         * 缓冲区
         */
        ByteBuffer buffer1 = ByteBuffer.allocate(num*5);
        /**
         * 文件输入流
         */
        FileInputStream in = new FileInputStream("/Users/yangyu/Downloads/compare.tmp");
        /**
         * 输入通道
         */
        FileChannel fin = in.getChannel();
        /**
         * 为读取做准备
         */
        buffer1.clear();
        System.out.println(buffer1.limit());
        /**
         * 读取
         */
        fin.read(buffer1);
        fin.close();

        long endTime = System.currentTimeMillis();
        System.out.println("ms:" + (endTime - startTime));
        buffer1.flip();
        System.out.println(buffer1.limit());
    }

    /**
     * 使用MappedByteBuffer,通过FileChannel将文件映射到内存
     * 时间:112ms
     * @throws IOException
     */
    @Test
    public void useRandomAccess() throws IOException {
        long startTime = System.currentTimeMillis();
        int num = 2000*2000;

        /**
         * 使用可随机访问位置的RandomAccessFile
         */
        RandomAccessFile file = new RandomAccessFile("/Users/yangyu/Downloads/compare.tmp","rw");
        /**
         * 获取通道Channel
         */
        FileChannel fileChannel = file.getChannel();
        /**
         * 将文件映射到缓冲区MappedByteBuffer
         */
        MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE,0,num*4);
        /**
         * 写文件
         */
        for (int i = 0; i < num; i++) {
            mappedByteBuffer.putInt(i);
        }
        fileChannel.close();

        int data=0;
        RandomAccessFile file1 = new RandomAccessFile("/Users/yangyu/Downloads/compare.tmp","rw");
        FileChannel fc = file1.getChannel();
        MappedByteBuffer mappedByteBuffer1 = fc.map(FileChannel.MapMode.READ_WRITE,0,file1.length());
        /**
         * 读文件
         */
        while (mappedByteBuffer1.hasRemaining()){
            data = mappedByteBuffer1.getInt();
        }
        fc.close();
        long endTime = System.currentTimeMillis();
        System.out.println("ms:" + (endTime - startTime));
        System.out.println(data);
    }
}

结论非常明显啦,以后再使用IO读写文件的时候,多使用NIO MappedByteBuffer吧,毕竟NIO比老IO性能好太多啦。

时间: 2024-10-10 23:13:35

Java--Stream,NIO ByteBuffer,NIO MappedByteBuffer性能对比的相关文章

Java Tomcat vs PHP CLI Server 性能对比

测试环境: Ubuntu 14.04 with i5-3230M Tomcat 8.0.5 with 64bit jre1.7.0_55 PHP 5.5.8 with Zend OPcache v7.0.3-dev 测试脚本: 显示当前服务器时间 Java Tomcat: t.jsp <%@ page session="false" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8&

Tomcat 8(十)HTTP/AJP Connector、Bio/Nio/Apr性能对比

Tomcat 8(七)解读Bootstrap介绍过,Connector初始化/启动的时候,将初始化/启动内部的ProtocolHandler.其实ProtocolHandler只是个接口 ProtocolHandler的UML图(以下这些类在org.apache.coyote包下) 创建Connector对象时,Connector的构造函数内会根据server.xml的Connector标签的配置创建ProtocolHandler(默为Http11NioProtocol) public Conn

nio和io拷贝文件性能对比

代码如下: 1 package my; 2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedOutputStream; 5 import java.io.BufferedReader; 6 import java.io.BufferedWriter; 7 import java.io.File; 8 import java.io.FileInputStream; 9 import java.io.FileOutputS

5种调优Java NIO和NIO.2的方式

Java NIO(New Input/Output)——新的输入/输出API包——是2002年引入到J2SE 1.4里的.Java NIO的目标是提高Java平台上的I/O密集型任务的性能.过了十年,很多Java开发者还是不知道怎么充分利用NIO,更少的人知道在Java SE 7里引入了更新的输入/输出 API(NIO.2).这篇教程展示了5个在Java编程的一些常见场景里使用NIO和NIO.2包的简单示例. NIO和NIO.2对于Java平台最大的贡献是提高了Java应用开发中的一个核心组件的

Java NIO、NIO.2学习笔记

相关学习资料 http://www.molotang.com/articles/903.html http://www.ibm.com/developerworks/cn/education/java/j-nio/j-nio.html 目录 1. NIO.NIO.2简介 2. NIO中的关键技术 1. NIO.NIO.2简介 Java中的输入流.输出流都是阻塞式的输入.输出.不仅如此,传统的输入流.输出流都是通过字节的移动来处理的(即使是字符流,在底层也是通过字节流来进行处理的),也就是说,面向

初理解Java中的BIO,NIO,AIO

初识: java 中的 BIO.NIO和 AIO 理解为是 Java 语言对操作系统的各种 IO 模型的封装.程序员在使用这些 API 的时候,不需要关心操作系统层面的知识,也不需要根据不同操作系统编写不同的代码.只需要使用Java的API就可以了. 在讲 BIO,NIO,AIO 之前先来回顾一下这样几个概念:同步与异步,阻塞与非阻塞. 同步与异步: 同步: 同步就是发起一个调用后,被调用者未处理完请求之前,调用不返回. 异步: 异步就是发起一个调用后,立刻得到被调用者的回应表示已接收到请求,但

NIO byteBUffer 讲解 及Mina 源码分析

1.传统的socket: 阻塞式通信模式 tcp连接: 与服务器连接时 .必须等到连接成功后 才返回 . udp连接: 客户端发送数据 ,必须等到发送成功后返回 . 每建立一个 Scoket连接时, 同事创建一个新线程对该 Socket进行单独通信(采用阻塞式通信 ) 这种方式具有很高的响应速度,并且控制起来也很简单,在连接数较少的时候非常有效,但是如果 对每一个连接都产生一个线程的无疑是对系统资源的一种浪费,如果连接数较多将会出现资源不足的情况 2.1NIO 设计背后的基石:反应器模式,用于事

Java I/O and NIO [reproduced]

Java I/O and NIO.2---Five ways to maximize Java NIO and NIO.2---Build more responsive Java applications with the New Input/Output APIs Java NIO -- the New Input/Output API package-- was introduced with J2SE 1.4 in 2002. Java NIO's purpose was to impr

java,Socket,NIO随笔记录

这个答案答的很好.Socket与SocketChannel是俩套api而已,对于网络tcp通信而言不会关心你上层是用何api实现通信的.所以答案是肯定的.SocketChannel可以设置为非阻塞的,所以在某种情况下性能更好,线程不会被挂住.SocketChannel还能注册selector和感兴趣的事件.selector多路复用器这里就不多做介绍了. 在这里介绍一下通信过程中数据的流动过程.首先当数据被网卡接收后,会被保存到内核中,电脑进行拆包解析,看源端口号,会将此数据包保存到对应链接的tc