本文介绍了不同的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. 《JAVASCRIPT高级程序设计》节点层次和DOM操作技术

    DOM可以将任何HTML和XML文档描绘成一个由多层次节点构成的结构.节点分为几种不同的类型,每种类型分别表示文档中不同的信息,每种类型都继承与Node接口,因此都共同享有一些属性和方法,同时,也拥有 ...

  2. 【福利大放送】不止是Android,Github超高影响力开源大放送,学习开发必备教科书

    一.写在前面 最近项目重构,时间贼多,也没什么时间更新博客,个人的开源项目也是多时没有更新了:github地址,然而没有更新不代表我不在乎,后面一有空还是会继续提交的. 还是来冒个泡,给大家献上一些福 ...

  3. java字符串比较及小数浮点型的使用

    import java.text.DecimalFormat; /* * 小数类型的常量默认是double类型,声明float类型的常量需要使用F作为后缀. * * 关于equals()和==: 对于 ...

  4. 【easyui】之treegrid的分页

    easyui官网给的treegrid的分页是相当的复杂,我们来简化一下! 首先treegrid 分页和 datagrid一样需要设置一系列参数! 如下: depTreeGrid=$("#de ...

  5. AngularJS2环境配置

    所使用到的文件目录结构如下所示: 1.      创建配置文件: 1.1.  创建目录: mkdir angular-quickstart cd angular-quickstart 1.2.  载入 ...

  6. [PHP] PHP1 与 CGI

    早期,一个web程序通过cgi方式提供数据处理,编写cgi程序可以用不同的语言. 这个过程是,我们生成一个服务端可执行程序,处理 web server 传过来的请求,(设置header头)然后返回数据 ...

  7. GDKOI2015滚粗记

    又是愉悦的滚粗了hahaha(特别不甘心啊啊啊) 其实去比赛每次都一样啦,就是每次吃饭睡觉补番考试评讲互黑跪烂什么的,这次就不用说了啦,先把老师要求写的东西贴出来再写点别的啦 这次暴露了很多问题,首先 ...

  8. 3553: [Shoi2014]三叉神经树(树链剖分)

    这道题特别恶心,首先我们可以发现更改的就是出现连续的一或二,那么就用线段树+树链剖分找到这个范围 想到是不难想,就是打起来恶心罢了= = CODE: #include<cstdio> #i ...

  9. iOS 创建一个在退出登录时可以销毁的单例

    一.单例简介 单例模式是在软件开发中经常用的一种模式.单例模式通俗的理解是,在整个软件生命周期内,一个类只能有一个实例对象存在. 二.遇到的问题 在平时开发使用单例的过程中,有时候会有这样的需求,在用 ...

  10. 每天一个Linux命令(18)--locate命令

    locate让使用者可以很快速的搜寻档案系统内是否有指定的档案.器方法是先建立一个包括系统内所有档案名称及路径的数据库,之后当寻找时就需查询这个数据库,而不必实际深入档案系统之中了.在一般的 ditr ...