本文介绍了不同的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. OGG学习笔记04-OGG复制部署快速参考

    OGG学习笔记04-OGG复制部署快速参考 源端:Oracle 10.2.0.5 RAC + ASM 节点1 Public IP地址:192.168.1.27 目标端:Oracle 10.2.0.5 ...

  2. TCP&UDP

    TCP(传输控制协议) 建立连接,形成传输数据的通道 在连接中进行大数据传输(数据大小不受限制) 通过三次握手完成连接,是可靠协议,安全送达(三次握手向服务器发送请求,响应请求回复,发送数据) 必须建 ...

  3. asp.net权限认证篇外:集成域账号登录

    在之前的我们已经讲过asp.net权限认证:Windows认证,现在我们来讲讲域账号登录, 这不是同一件事哦,windows认证更多的是对资源访问的一种权限管控,而域账号登录更多的是针对用户登录的认证 ...

  4. java系列笔记---正则表达式(2)

    正则表达式 说真的正则表达式真不好写,当我收集资料准备开始写的时候,发现收集的东西越来越多范围也越来越广,我文章的前提就是文章要清晰, 在缕清自己思路之后,我从先简后难的方式来写有关正表达式,你们如果 ...

  5. 基于python的互联网软件测试开发(自动化测试)-全集合

    基于python的互联网软件测试开发(自动化测试)-全集合 1   关键字 为了便于搜索引擎收录本文,特别将本文的关键字给强调一下: python,互联网,自动化测试,测试开发,接口测试,服务测试,a ...

  6. cookie,sessionstorage,localstorage区别

    都是保存在浏览器端,且同源的,区别如下: 1.携带 cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递. 而sessionStorage和local ...

  7. Visual Studio 2017 RC 初探安装

    上次看到博客介绍 Visual Studio 2017 RC,看到其中一个改进是启动很快,这是一大进步,也是低配电脑的程序员的期望.不过还没体验,是驴是骡子拉出来看看,这不就开始下载. 1.打开官网: ...

  8. angular1.5 Components

    如今前端界angular react vue三大框架并驾齐驱,其中有一个共同点就是组件化开发,这也符合w3c 推行Web Components的趋势.现如今不懂组件化开发的前端绝对不是好厨子.跳槽新公 ...

  9. 封装keyframes插件

    模仿jquery,使用简单,自动添加浏览器前缀 var keyframes = new SHBKerframes(); keyframes.define([{ name:'myAnimate', 0% ...

  10. 5个Android开发中比较常见的内存泄漏问题及解决办法

    android中一个对象已经不需要了,但是其他对象还持有他的引用,导致他不能回收,导致这个对象暂存在内存中,这样内存泄漏就出现了.   内存泄漏出现多了,会是应用占用过多的没存,当占用的内存超过了系统 ...