本文介绍了不同的IO方式以及他们之间的效率比较

1.一次读取写入单个字节(读取400M的文件浪费了很久,等了很久没读取完成,证明其效率很差)

 public class CopyFileDemo {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("a.txt");
FileOutputStream fos = new FileOutputStream("b.txt"); // 方式一:一次读取写入单个字节
int i = 0;
while ((i = fis.read()) != -1) {
fos.write(i);
}
fos.close();
fis.close();
}
}

2.一次读取写入多个字节(读取400M的文件700ms)

 public class CopyFileDemo {
public static void main(String[] args) throws IOException {
  FileInputStream fis = new FileInputStream("a.txt");
  FileOutputStream fos = new FileOutputStream("b.txt");
  // 方式二:一次读取写入一个字节数组
  byte[] by = new byte[1024];
  int len = 0;
  while ((len = fis.read(by)) != -1) {
    fos.write(by, 0, len);
  }
  fos.close();
  fis.close();
  }
}

3.文件流输入输出(读取400M的文件5000ms,为什么更慢呢,猜测是readline这里,大神可以指出来)

 public class CopyFileDemo3 {
public static void main(String[] args) throws IOException {
BufferedReader br=new BufferedReader(new FileReader("a.txt"));
//如果d文件中有数据,true表示继续往文件中追加数据
BufferedWriter bw=new BufferedWriter(new FileWriter("d.txt",true)); String line=null;
//高效字符输入流的特有方法readline(),每次读取一行数据
while((line=br.readLine())!=null){
bw.write(line);
//高效字符输出流的特有方法newline()
bw.newLine();
//将缓冲区中的数据刷到目的地文件中
bw.flush();
}
//关闭流,其实关闭的就是java调用的系统底层资源。在关闭前,会先刷新该流。
bw.close();
br.close();
}
}

BufferedInputStream 会根据情况自动为我们预读更多的字节数据到它自己维护的一个内部字节数组缓冲区中,这样我们便可以减少系统调用次数,从而达到其缓冲区的目的。所以要明确的一点是 BufferedInputStream 的作用不是减少 磁盘IO操作次数(这个OS已经帮我们做了),而是通过减少系统调用次数来提高性能的。

4.NIO读取 (400M的视频文件,读取要长达700ms)

 public class ReadDemo{
public static void main(String[] args) throws IOException {
File file = new File("sdtgj.mp4");
FileInputStream in = new FileInputStream(file);
FileChannel channel = in.getChannel();
ByteBuffer buff = ByteBuffer.allocate(1024); long begin = System.currentTimeMillis();
while (channel.read(buff) != -1) {
buff.flip();
buff.clear();
}
long end = System.currentTimeMillis();
System.out.println("time is:" + (end - begin)+"毫秒 "+"读取 "+file.getName());
}
}

5.内存映射读取 (400M的视频文件,读取只要100ms)

 public class ReadDemo{

      static final int BUFFER_SIZE = 1024;  

         public static void main(String[] args) throws Exception {  

             File file = new File("sdtgj.mp4");
FileInputStream in = new FileInputStream(file);
FileChannel channel = in.getChannel();
MappedByteBuffer buff = channel.map(FileChannel.MapMode.READ_ONLY, 0,
channel.size()); byte[] b = new byte[1024];
int len = (int) file.length(); long begin = System.currentTimeMillis(); for (int offset = 0; offset < len; offset += 1024) { if (len - offset > BUFFER_SIZE) {
buff.get(b);
} else {
buff.get(new byte[len - offset]);
}
} long end = System.currentTimeMillis();
System.out.println("time is:" + (end - begin)+"毫秒 "+"读取 "+file.getName()); }
}
MappedByteBuffer 不受JVM堆大小控制,速度最快。
MappedByteBuffer 的要点:
  1. java通过java.nio包来支持内存映射IO。
  2. 内存映射文件主要用于性能敏感的应用,例如高频电子交易平台。
  3. 通过使用内存映射IO,你可以将大文件加载到内存
  4. 内存映射文件可能导致页面请求错误,如果请求页面不在内存中的话。
  5. 映射文件区域的能力取决于于内存寻址的大小。在32位机器中,你不能访问超过4GB或2 ^ 32(以上的文件)。
  6. 内存映射IO比起Java中的IO流要快的多。
  7. 加载文件所使用的内存是Java堆区之外,并驻留共享内存,允许两个不同进程共享文件。
  8. 内存映射文件读写由操作系统完成,所以即使在将内容写入内存后java程序崩溃了,它将仍然会将它写入文件直到操作系统恢复。
  9. 出于性能考虑,推荐使用直接字节缓冲而不是非直接缓冲。
  10. 不要频繁调用MappedByteBuffer.force()方法,这个方法意味着强制操作系统将内存中的内容写入磁盘,所以如果你每次写入内存映射文件都调用force()方法,你将不会体会到使用映射字节缓冲的好处,相反,它(的性能)将类似于磁盘IO的性能。
  11. 万一发生了电源故障或主机故障,将会有很小的机率发生内存映射文件没有写入到磁盘,这意味着你可能会丢失关键数据。

文件IO理解的更多相关文章

  1. 转:Linux 文件IO理解

    源地址http://blog.csdn.net/lonelyrains/article/details/6604851 linux文件IO操作有两套大类的操作方式:不带缓存的文件IO操作,带缓存的文件 ...

  2. 转 漫谈linux文件IO

    在Linux 开发中,有几个关系到性能的东西,技术人员非常关注:进程,CPU,MEM,网络IO,磁盘IO.本篇文件打算详细全面,深入浅出.剖析文件IO的细节.从多个角度探索如何提高IO性能.本文尽量用 ...

  3. 文件IO

    在unix世界中视一切为文件,无论最基本的文本文件还是网络设备或是u盘,在内核看来它们的本质都是一样的.大多数文件IO操作只需要用到5个函数:open . read . write . lseek 以 ...

  4. 漫谈linux文件IO

    在Linux 开发中,有几个关系到性能的东西,技术人员非常关注:进程,CPU,MEM,网络IO,磁盘IO.本篇文件打算详细全面,深入浅出.剖析文件IO的细节.从多个角度探索如何提高IO性能.本文尽量用 ...

  5. Linux学习记录--文件IO操作相关系统编程

    文件IO操作相关系统编程 这里主要说两套IO操作接口,各自是: POSIX标准 read|write接口.函数定义在#include<unistd.h> ISO C标准 fread|fwr ...

  6. (代码篇)从基础文件IO说起虚拟内存,内存文件映射,零拷贝

    上一篇讲解了基础文件IO的理论发展,这里结合java看看各项理论的具体实现. 传统IO-intsmaze 传统文件IO操作的基础代码如下: FileInputStream in = new FileI ...

  7. (理论篇)从基础文件IO说起虚拟内存,内存文件映射,零拷贝

    为了快速构建项目,使用高性能框架是我的职责,但若不去深究底层的细节会让我失去对技术的热爱. 探究的过程是痛苦并激动的,痛苦在于完全理解甚至要十天半月甚至没有机会去应用,激动在于技术的相同性,新的框架不 ...

  8. 17、文件IO详解及实例

    上篇文章已经讲过了文件系统的一些基本的概念,这里首先对文件IO进行详细的学习,文件IO也称为系统调用IO,是操作系统为"用户态"运行的进程和硬件交互提供的一组接口,即操作系统内核留 ...

  9. linux 文件IO

    1.文件描述符 (1)文件描述符的本质是一个数字,这个数字本质上是进程表中文件描述符表的一个表项,进程通过文件描述符作为index去索引查表得到文件表指针,再间接访问得到这个文件对应的文件表.(2)文 ...

随机推荐

  1. iOS initWithFrame、initWithCoder、awakeFromNib的区别解析

    当我们需要自定义一个View控件时,会有 initWithFrame.initWithCoder.awakeFromNib 这三个系统方法,关于这三个方法何时调用,如何调用,有时候可能很多人会弄混淆. ...

  2. 从0到1学习node之简易的网络爬虫

    本文地址: http://www.xiabingbao.com/node/2017/01/19/node-spider.html 我们这节的目标是学习完本节课程后,能进行网页简单的分析与抓取,对抓取到 ...

  3. ios NSString拼接方法总结

    NSString* string; // 结果字符串 02 NSString* string1, string2; //已存在的字符串,需要将string1和string2连接起来 03   04 / ...

  4. 【Unity3d游戏开发】浅谈UGUI中的Canvas以及三种画布渲染模式

    一.Canvas简介 Canvas画布是承载所有UI元素的区域.Canvas实际上是一个游戏对象上绑定了Canvas组件.所有的UI元素都必须是Canvas的自对象.如果场景中没有画布,那么我们创建任 ...

  5. 去除android或者iOS系统默认的一些样式总结

    ios系统中元素被触摸时产生的半透明灰色遮罩怎么去掉 iOS用户点击一个链接,会出现一个半透明灰色遮罩, 如果想要禁用,可设置-webkit-tap-highlight-color的alpha值为0, ...

  6. js精要之模块模式

    // 模块模式是一种用于创建拥有私有数据的单件对象的模式,基本做法是使用立调函数(IIFE)来返回一个对象 var yourObjet = (function(){ // 私有数据 return { ...

  7. web前端 兼容性问题

    1:position属性使用过多或使用位置不恰当引起滚动时页面错乱 浏览器环境:ie7 position:relative; 网页上最直接表现就是极具破坏性的滚动错位,问题产生来自ie7自身渲染解析出 ...

  8. 使用VS Code从零开始开发调试.NET Core 1.1

    使用VS Code 从零开始开发调试.NET Core 1.1.无需安装VS 2017 RC 即可开发.NET Core 1.1. .NET Core 1.1 发布也有一段时间了,最大的改动是从 pr ...

  9. 使用express.js框架一步步实现基本应用以及构建可扩展的web应用

    最近过年在家有点懈怠,但是自己也不断在学习新的前端技术,在家琢磨了express.js的web框架. 框架的作用就是提高开发效率,快速产出结果.即使不使用框架,我们也会在开发过程中逐渐形成构成框架. ...

  10. python面向对象编程对象和实例的理解

    给你一个眼神,自己体会