一、实验背景

最近在考虑一个问题:“如果快速地向文件中写入数据”,java提供了多种文件写入的方式,效率上各有异同,基本上可以分为如下三大类:字节流输出、字符流输出、内存文件映射输出。前两种又可以分为带buffer及不带buffer。

二、实验目标

通过实验找出单线程场景下文件写入效率最高的方式,并量化各种文件写入方式在效率上的差距。

三、实验设计

为减少其他环节的影响,示例代码使用循环输出同一字符串多次的方式测试整个输出环节的耗时,通过耗时、服务器资源使用情况(cpu、内存使用)等指标评判各种文件写入方式的效率好坏。

四、实验环境

OS: windows 7 64bit

cpu: 4core, 主频:2.4GHZ

mem:6G

五、实验步骤

总共进行8次输出实验,依次输出的文件大小为:10M、50M、100M、200M、500M、800M、1G、2G;

每次输出后记录各种方式的耗时情况,并填表。

五、实验结果

表1、java各种文件写入方法效率对比实验时延数据表

表1、java各种文件写入方法效率对比实验时延结果图(含大文件)

表2、java各种文件写入方法效率对比实验时延结果图(不含大文件)

 

图2、文件大小为2048m时,各个写入方式执行任务时cpu使用情况:

图3、文件大小为2048m时,各个写入方式执行任务时jvm内存使用情况

图4、文件大小为2048m时,各个写入方式执行任务时物理内存使用情况:

上图中红圈中为‘FileChannel’方式下的物理内存使用情况。

六、实验结论

1、基本上,五种写入方式的时延从小到大排序为:FileChannel<BufferedOutputStream<FileOutputStream<BufferedWriter<FileWriter;从表1、图1;可以看出;且该规律在小文件写入的情景下,更为明显,图2可以看出;

2、在同样文件大小写入的场景中,通常意义上带buffer的字节流输入/字符流输入比不带buffer的对应流效率要高;

3、各个写入方式的jvm cpu和内存使用情况大致相当,从图2和图3可以看出;

4、文件达到一定大小后( fileSize >=1.5G ),FileChannel的时延变得很大且不稳定,从图1最右边可以看出;同时,物理内存的使用量基本和写入文件大小相当,从图4可以看出;原因在于FileChannel使用MappedByteBuffer写入,这个buffer是direct buffer,直接操作物理内存写入,故而造成物理内存消耗严重。

5、小文件写入的场景下(1M左右),FileChannel有些大材小用了,效率上反而没有字节流效率高。

综上,我们可以得到几条有价值的使用经验:

1、小文件(几M的文件)写入时,使用常规的io输入就行,最优选择是BufferedInportStream,没有必要使用nio的FileChannel;

2、大文件(fileSize > 1G,这是个经验值,需要根据具体环境具体分析)写入时,使用FileChannel需要小心物理内存的瓶颈带来的写入效率低下,可以考虑使用分段写入的方式(TODO:后续实验给出);

3、其他场景下,如果效率优先的考虑,则优先选择FileChannel写入文件。

七、demo

参考git仓库:https://github.com/daoqidelv/io-demo

java中多种写文件方式的效率对比实验的更多相关文章

  1. java中IO写文件工具类

    以下是一些依据经常使用java类进行组装的对文件进行操作的类,平时,我更喜欢使用Jodd.io中提供的一些对文件的操作类,里面的方法写的简单易懂. 当中jodd中提供的JavaUtil类中提供的方法足 ...

  2. java中多种方式读文件

    转自:http://www.jb51.net/article/16396.htm java中多种方式读文件 一.多种方式读文件内容. 1.按字节读取文件内容 2.按字符读取文件内容 3.按行读取文件内 ...

  3. 【练习】Java中的读文件,文件的创建,写文件

    前言 大家好,给大家带来Java中的读文件,文件的创建,写文件的概述,希望你们喜欢 读文件 public static void read(String path,String filename){ ...

  4. Java中的读文件,文件的创建,写文件

    前言 大家好,我是 Vic,今天给大家带来Java中的读文件,文件的创建,写文件的概述,希望你们喜欢 示意图 读文件 public static void read(String path,Strin ...

  5. Java文件操作类效率对比

    前言 众所周知,Java中有多种针对文件的操作类,以面向字节流和字符流可分为两大类,这里以写入为例: 面向字节流的:FileOutputStream 和 BufferedOutputStream 面向 ...

  6. java 中获得 资源文件方法

    1 java 中获取资源文件的方法 项目目录如下 获取当前项目的目录路径 方法一:使用类名 MergeDocHandler.class.getClassLoader().getResource(&qu ...

  7. Java中LinkedList的fori和foreach效率比较

    在<Java中ArrayList的fori和foreach效率比较>中对ArrayList的两种循环方式进行了比较,本次对LinkedList的两种遍历方式进行效率的比较. 1. list ...

  8. JS 和 Java 中URL特殊字符编码方式

    前几天遇到url特殊字符编码的问题,在这里整理一下: JavaScript 1.  编码 escape(String) 其中某些字符被替换成了十六进制的转义序列. 解码 unescape(String ...

  9. Java中创建操作文件和文件夹的工具类

    Java中创建操作文件和文件夹的工具类 FileUtils.java import java.io.BufferedInputStream; import java.io.BufferedOutput ...

随机推荐

  1. unity插件开发——一个例子:简单的svn集成

    在unity开发过程中,通常我们习惯性地在Windows操作系统下使用svn进行版本管理,而每次提交更新,都需要回到文件夹下的这种操作让人无法忍受.是不是可以集成svn到unity中呢?查了一圈uni ...

  2. Alamofire源码解读系列(十一)之多表单(MultipartFormData)

    本篇讲解跟上传数据相关的多表单 前言 我相信应该有不少的开发者不明白多表单是怎么一回事,然而事实上,多表单确实很简单.试想一下,如果有多个不同类型的文件(png/txt/mp3/pdf等等)需要上传给 ...

  3. CodeFirst的一些操作!!

    CodeFirst的一些操作!! 转载 2016-08-05 21:03:32 1 首先是codefirst怎么做,这个首先肯定要引入EntityFramework,然后在model中创建实体类,例如 ...

  4. Androidstudio2.0.0下载,欢迎下载

    Androidstudio开发工具很实用,但是没了Google下载还是蛮麻烦的,所以呢Eric就向大家提供了下载的地址,其实就是从自己网盘考过来的,大家可以下载的. http://pan.baidu. ...

  5. 重温Javascript(二)

    对象 可以想象成散列表,键值对,值可以是数据或函数 创建对象的方式 1.工厂模式 function createPerson(name, age, job){ var o = new Object() ...

  6. 【Egret】在WebStorm里使用Egret Engine 的注意点

    1.开启代码提示 2.修改egret code后,自动编译新egret code 按照下图进行设置: ①打开"File-settings" ② ③ (PS:webstorm打开目录 ...

  7. 随机跳转页面之使用VBA公共变量

    p{ font-size: 15px; } .alexrootdiv>div{ background: #eeeeee; border: 1px solid #aaa; width: 99%; ...

  8. 老李分享:loadrunne动态查询db2数据库

    老李分享:loadrunne动态查询db2数据库   poptest老李认为性能测试脚本开发不仅仅涉及到脚本开发的技术层面,同时也要对一些其他技术有所了解动态链接库的技术,线程安全等等,建议在做下面的 ...

  9. Android多渠道打包

    项目需要,简单2步实现(由于简单,所以对大量渠道打包不是最优的),比如1000个渠道同时打包的话可能花费的时间会过长.不过目前该方法能满足绝大需求了...根据截图一步一步走: 第一步 设置配置清单文件 ...

  10. canvas画布

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...