一、实验背景

最近在考虑一个问题:“如果快速地向文件中写入数据”,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. win8效果的横向布局

    有一个月没写过博客了,自己的博客也没有看过,前段时间一直在忙着写代码,公司有一个制漆的产品,与传统纵向布局不一样,要求页面横向布局,类似win8的那种布局效果,最开始,我也没有什么头绪,然后硬着头皮做 ...

  2. adobe edge animate 和 adobe animate cc 有啥区别?

    经常有人问这两款软件的区别,每次都要打字好烦,特此总结发帖如下: 一.首先各自软件介绍 ①adobe edge animate 是adobe公司早期推出的一款网页互动工具.通过HTML+CSS+Jav ...

  3. 【转】轻应用、Web App、Native App三者分别是什么?

      一.什么是Native app Native App是一种基于智能手机本地操作系统如IOS.Android.WP并使用原生程式编写运行的第三方应用程序,也叫地app.NativeApp因为位于平台 ...

  4. linux redis安装

    redis官网地址:http://www.redis.io/ 在Linux下安装Redis非常简单,具体步骤如下(官网有说明): 1.下载源码,解压缩后编译源码. $ wget http://down ...

  5. plist文件的相关操作

    本文概要 1.plist文件的简介 2.在Xcode中创建plist文件 3.在Xcode中将plist文件转换成数组或者字典对象 4.将数组或者字典对象转换成plist文件并且存储 详细介绍 1.p ...

  6. MySQL关于check约束无效的解决办法

    首先看下面这段MySQL的操作,我新建了一个含有a和b的表,其中a用check约束必须大于0,然而我插入了一条(-2,1,1)的数据,其中a=-2,也是成功插入的. 所以MySQL只是check,但是 ...

  7. Java NIO之通道

    一.前言 前面学习了缓冲区的相关知识点,接下来学习通道. 二.通道 2.1 层次结构图 对于通道的类层次结构如下图所示. 其中,Channel是所有类的父类,其定义了通道的基本操作.从 Channel ...

  8. GreenDao与Rx的完美搭配

    作为Android开发者,一定不会对 GreenDao 和 ReactiveX 陌生. GreenDao   号称Android最快的关系型数据库 ReactiveX    Rx是一个编程模型,目标是 ...

  9. iOS 播放GIf图, 动态效果

    一.如果你集成了SDWebImage , 有一个很简单的方法 //导入sdwebImage的某个头文件 #import "UIImage+GIF.h" _bubble1.backg ...

  10. SourceTree 无法查看组织仓库

    error log: Pushing to remote: Repository not found. 在使用SourceTree进行版本控制,代替git命令行,而且作为免费 跨平台 功能完备的git ...