java-IO操作性能对比

在软件系统中,IO速度比内存速度慢,IO读写在很多情况下会是系统的瓶颈。

在java标准IO操作中,InputStream和OutputStream提供基于流的IO操作,以字节为处理单位;Reader和Writer实现了Buffered缓存,以字符为处理单位。

从Java1.4开始,增加NIO(New IO),增加缓存Buffer和通道Channel,以块为处理单位,是双向通道(可读可写,类似RandomAccessFile),支持锁和内存映射文件访问接口,大大提升了IO速度。

以下例子简单测试常见IO操作的性能速度。

/**
 * 测试不同io操作速度
 *
 * @author peter_wang
 * @create-time 2014-6-4 下午12:52:48
 */
public class SpeedTest {
    private static final String INPUT_FILE_PATH = "io_speed.txt";
    private static final String OUTPUT_FILE_PATH = "io_speed_copy.txt";

    /**
     * @param args
     */
    public static void main(String[] args) {
        long ioStreamTime1 = ioStreamCopy();
        System.out.println("io stream copy:" + ioStreamTime1);

        long ioStreamTime2 = bufferedStreamCopy();
        System.out.println("buffered stream copy:" + ioStreamTime2);

        long ioStreamTime3 = nioStreamCopy();
        System.out.println("nio stream copy:" + ioStreamTime3);

        long ioStreamTime4 = nioMemoryStreamCopy();
        System.out.println("nio memory stream copy:" + ioStreamTime4);
    }

    /**
     * 普通文件流读写
     *
     * @return 操作的时间
     */
    private static long ioStreamCopy() {
        long costTime = -1;
        FileInputStream is = null;
        FileOutputStream os = null;
        try {
            long startTime = System.currentTimeMillis();
            is = new FileInputStream(INPUT_FILE_PATH);
            os = new FileOutputStream(OUTPUT_FILE_PATH);
            int read = is.read();
            while (read != -1) {
                os.write(read);
                read = is.read();
            }
            long endTime = System.currentTimeMillis();
            costTime = endTime - startTime;
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            try {
                if (is != null) {
                    is.close();
                }
                if (os != null) {
                    os.close();
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        return costTime;
    }

    /**
     * 加入缓存的文件流读写, Reader默认实现缓存,只能读取字符文件,无法准确读取字节文件如图片视频等
     *
     * @return 操作的时间
     */
    private static long bufferedStreamCopy() {
        long costTime = -1;
        FileReader reader = null;
        FileWriter writer = null;
        try {
            long startTime = System.currentTimeMillis();
            reader = new FileReader(INPUT_FILE_PATH);
            writer = new FileWriter(OUTPUT_FILE_PATH);
            int read = -1;
            while ((read = reader.read()) != -1) {
                writer.write(read);
            }
            writer.flush();
            long endTime = System.currentTimeMillis();
            costTime = endTime - startTime;
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            try {
                if (reader != null) {
                    reader.close();
                }
                if (writer != null) {
                    writer.close();
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        return costTime;
    }

    /**
     * nio操作数据流
     *
     * @return 操作的时间
     */
    private static long nioStreamCopy() {
        long costTime = -1;
        FileInputStream is = null;
        FileOutputStream os = null;
        FileChannel fi = null;
        FileChannel fo = null;
        try {
            long startTime = System.currentTimeMillis();
            is = new FileInputStream(INPUT_FILE_PATH);
            os = new FileOutputStream(OUTPUT_FILE_PATH);
            fi = is.getChannel();
            fo = os.getChannel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            while (true) {
                buffer.clear();
                int read = fi.read(buffer);
                if (read == -1) {
                    break;
                }
                buffer.flip();
                fo.write(buffer);
            }
            long endTime = System.currentTimeMillis();
            costTime = endTime - startTime;
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            try {
                if (fi != null) {
                    fi.close();
                }
                if (fo != null) {
                    fo.close();
                }
                if (is != null) {
                    is.close();
                }
                if (os != null) {
                    os.close();
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        return costTime;
    }

    /**
     * nio内存映射操作数据流
     *
     * @return 操作的时间
     */
    private static long nioMemoryStreamCopy() {
        long costTime = -1;
        FileInputStream is = null;
        //映射文件输出必须用RandomAccessFile
        RandomAccessFile os = null;
        FileChannel fi = null;
        FileChannel fo = null;
        try {
            long startTime = System.currentTimeMillis();
            is = new FileInputStream(INPUT_FILE_PATH);
            os = new RandomAccessFile(OUTPUT_FILE_PATH, "rw");
            fi = is.getChannel();
            fo = os.getChannel();
            IntBuffer iIb=fi.map(FileChannel.MapMode.READ_ONLY, 0, fi.size()).asIntBuffer();
            IntBuffer oIb = fo.map(FileChannel.MapMode.READ_WRITE, 0, fo.size()).asIntBuffer();
            while(iIb.hasRemaining()){
                int read = iIb.get();
                oIb.put(read);
            }
            long endTime = System.currentTimeMillis();
            costTime = endTime - startTime;
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            try {
                if (fi != null) {
                    fi.close();
                }
                if (fo != null) {
                    fo.close();
                }
                if (is != null) {
                    is.close();
                }
                if (os != null) {
                    os.close();
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        return costTime;
    }

}

运行结果:

io stream copy:384
buffered stream copy:125
nio stream copy:12
nio memory stream copy:10

结论分析:

最普通的InputStream操作耗时较长,增加了缓存后速度增加了,用了nio和内存映射访问文件,速度最快。

java-IO操作性能对比

时间: 2024-08-03 17:25:43

java-IO操作性能对比的相关文章

Java中的NIO和IO的对比分析

总的来说,java中的IO和NIO主要有三点区别: IO                  NIO 面向流     面向缓冲 阻塞IO  非阻塞IO  无   选择器(Selectors) 1.面向流与面向缓冲 Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的. Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方.此外,它不能前后移动流中的数据.如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区. Java

Java IO编程全解(六)——4种I/O的对比与选型

转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7804185.html 前面讲到:Java IO编程全解(五)--AIO编程 为了防止由于对一些技术概念和术语的理解或者叫法不一致而引起歧义,这里对涉及到的专业术语或者技术用语做下声明:如果它们与其他一些地方的称呼不一致,请以本解释为准. 异步非阻塞I/O 很多人喜欢将JDK1.4提供的NIO框架成为异步非阻塞I/O,但是,如果严格按照UNIX网络编程模型和JDK的实现进行区分,实际上它只能被称为非阻塞I/

java io读取性能对比

背景 从最早bio的只支持阻塞的bio(同步阻塞) 到默认阻塞支持非阻塞nio(同步非阻塞+同步阻塞)(此时加入mmap类) 再到aio(异步非阻塞) 虽然这些api改变了调用模式,但真正执行效率上是否也会有所不同,对此进行了此次java io的性能测试 首先从github上找到了2个项目,然后自己也实现了一个性能对比的实现,以便熟悉各种api 项目1: https://github.com/stateIs0/io.benchmark https://www.jianshu.com/u/4342

解决hiveserver2报错:java.io.IOException: Job status not available - Error while processing statement: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask

用户使用的sql: select count( distinct patient_id ) from argus.table_aa000612_641cd8ce_ceff_4ea0_9b27_0a3a743f0fe3; 下面做不同的测试: 1.beeline -u jdbc:hive2://0.0.0.0:10000 -e "select count( distinct patient_id ) from argus.table_aa000612_641cd8ce_ceff_4ea0_9b27_

Java IO之简单输入输出

Java中的IO分为两个部分,以InputStream和Reader为基类的输入类,以OutputStream和Writer为基类的输出类.其中InputStream和OutputStream以字节为单位进行IO,而Reader和Writer以字符为单位. 除了输入输出,还有一系列类库称为Filter,或成为装饰器.对于输入可用FilterInputStream和FilterReader的派生类,输出可用FilterOutputStream和FilterWriter的派生类,其中FilterIn

java IO流 之 输入流 InputString()

学习java的重点之一:InputStream  字节输入流的使用 (1)FileInputstream: 子类,读取数据的通道 使用步骤: 1.获取目标文件:new File() 2.建立通道:new FileInputString() 3.读取数据:read() 4.释放资源:close() //一些默认要导入的包 import java.io.File; import java.io.FileInputStream; import java.io.IOException; 1 public

Java IO——堵塞式

目录     1.  File类   2.  InputStream和OutputStream   3.  Reader和Writer   4.  RandomAccessFile   5.  对象序列化   6.  标准I/O   7.  进程控制   内容     1.  File类   File类给人的感觉就是文件类,其实对其恰当的诠释却是Filepath(文件路径),java.io.File类不仅可以代表一个特定的文件,还可以代表一个目录下面的一组文件名称.当File指向一个文件集时,就

Java IO流(第二讲):File类

File是基于磁盘操作的I/O,Java多数IO都是实行流式操作,但是File不是,它不会读取文件信息或者向文件存储,它是直接处理文件的,它不会读取文件信息或者向文件存储,File对象可以用来获取或处理与磁盘文件相关的信息,例如权限,时间,日期和目录路径.File类的名字比较欺骗性,它其实并不仅仅代表一个特定文件名字,也可以代表文件目录下一系列文件名,用File存储数据存在很大的安全性,但是文件仍是我们存储数据以及共享数据的主要工具. 下面我们来解读File类在Java中的运用方式. 首先,我们

JAVA IO 序列化与设计模式

?更多技术干货请戳:听云博客 序列化 什么是序列化 序列化:保存对象的状态 反序列化:读取保存对象的状态 序列化和序列化是Java提供的一种保存恢复对象状态的机制 序列化有什么用 将数据保存到文件或数据库中时 将数据通过套接字在网络上传输时 通过 RPC RMI等传输对象时 如何序列化 实现Serializable接口 实现Externalizable接口 serialVersionUID的作用serialVersionUID建议给一个确定的值,不要由系统自动生成,否则在增减字段(不能修改字段类