文件IO理解
本文介绍了不同的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 的要点:
- java通过java.nio包来支持内存映射IO。
- 内存映射文件主要用于性能敏感的应用,例如高频电子交易平台。
- 通过使用内存映射IO,你可以将大文件加载到内存。
- 内存映射文件可能导致页面请求错误,如果请求页面不在内存中的话。
- 映射文件区域的能力取决于于内存寻址的大小。在32位机器中,你不能访问超过4GB或2 ^ 32(以上的文件)。
- 内存映射IO比起Java中的IO流要快的多。
- 加载文件所使用的内存是Java堆区之外,并驻留共享内存,允许两个不同进程共享文件。
- 内存映射文件读写由操作系统完成,所以即使在将内容写入内存后java程序崩溃了,它将仍然会将它写入文件直到操作系统恢复。
- 出于性能考虑,推荐使用直接字节缓冲而不是非直接缓冲。
- 不要频繁调用MappedByteBuffer.force()方法,这个方法意味着强制操作系统将内存中的内容写入磁盘,所以如果你每次写入内存映射文件都调用force()方法,你将不会体会到使用映射字节缓冲的好处,相反,它(的性能)将类似于磁盘IO的性能。
- 万一发生了电源故障或主机故障,将会有很小的机率发生内存映射文件没有写入到磁盘,这意味着你可能会丢失关键数据。
文件IO理解的更多相关文章
- 转:Linux 文件IO理解
源地址http://blog.csdn.net/lonelyrains/article/details/6604851 linux文件IO操作有两套大类的操作方式:不带缓存的文件IO操作,带缓存的文件 ...
- 转 漫谈linux文件IO
在Linux 开发中,有几个关系到性能的东西,技术人员非常关注:进程,CPU,MEM,网络IO,磁盘IO.本篇文件打算详细全面,深入浅出.剖析文件IO的细节.从多个角度探索如何提高IO性能.本文尽量用 ...
- 文件IO
在unix世界中视一切为文件,无论最基本的文本文件还是网络设备或是u盘,在内核看来它们的本质都是一样的.大多数文件IO操作只需要用到5个函数:open . read . write . lseek 以 ...
- 漫谈linux文件IO
在Linux 开发中,有几个关系到性能的东西,技术人员非常关注:进程,CPU,MEM,网络IO,磁盘IO.本篇文件打算详细全面,深入浅出.剖析文件IO的细节.从多个角度探索如何提高IO性能.本文尽量用 ...
- Linux学习记录--文件IO操作相关系统编程
文件IO操作相关系统编程 这里主要说两套IO操作接口,各自是: POSIX标准 read|write接口.函数定义在#include<unistd.h> ISO C标准 fread|fwr ...
- (代码篇)从基础文件IO说起虚拟内存,内存文件映射,零拷贝
上一篇讲解了基础文件IO的理论发展,这里结合java看看各项理论的具体实现. 传统IO-intsmaze 传统文件IO操作的基础代码如下: FileInputStream in = new FileI ...
- (理论篇)从基础文件IO说起虚拟内存,内存文件映射,零拷贝
为了快速构建项目,使用高性能框架是我的职责,但若不去深究底层的细节会让我失去对技术的热爱. 探究的过程是痛苦并激动的,痛苦在于完全理解甚至要十天半月甚至没有机会去应用,激动在于技术的相同性,新的框架不 ...
- 17、文件IO详解及实例
上篇文章已经讲过了文件系统的一些基本的概念,这里首先对文件IO进行详细的学习,文件IO也称为系统调用IO,是操作系统为"用户态"运行的进程和硬件交互提供的一组接口,即操作系统内核留 ...
- linux 文件IO
1.文件描述符 (1)文件描述符的本质是一个数字,这个数字本质上是进程表中文件描述符表的一个表项,进程通过文件描述符作为index去索引查表得到文件表指针,再间接访问得到这个文件对应的文件表.(2)文 ...
随机推荐
- CodeForces 721A
A. One-dimensional Japanese Crossword time limit per test:1 second memory limit per test:256 megabyt ...
- 转:Spring FactoryBean源码浅析
http://blog.csdn.net/java2000_wl/article/details/7410714 在Spring BeanFactory容器中管理两种bean 1.标准Java Bea ...
- IOS解析XML
XML也许是我们储存数据和通讯数据中最常见的一种简易方式,当我们来到XML的海洋时,我们会发现当我们用iPhone程序解析XML时,我们是有如此多的选项,让人眼花缭乱.iOS SDK本身就带有两种不同 ...
- 微信小程序----关于变量对象data 和 前端wxml取后台js变量值
(一)页面变量对象data 对象data 有两个方面用途 第一,前端wxml的数据渲染是通过设置此对象中定义的变量进行关联展现的 第二,定义JS页面中的页面局部变量,使其整个页面中可使用或调用 对象d ...
- Android几行代码实现实时监听微信聊天
实现效果: 实时监听当前聊天页面的最新一条消息,如图: 实现原理: 同样是利用AccessibilityService辅助服务,关于这个服务类还不了解的同学可以先看下我上一篇关于 ...
- SQL 数据库基本知识
SQL:Structured Quety Language SQL SERVER是一个以客户/服务器(c/s)模式访问.使用Transact-SQL语言的关系型数据库管理子系统(RDBMS) DBMS ...
- sqlcmd命令导入大容量的SQL本地文件至SQL server 2008
由于开发工作在测试环境,需要构造测试数据,经常遇到100+M大小的*.sql文件需要导入到测试库的情况,由于SSMS里对导入文件的大小有限制: 会出现上图的报错!上网查了下,超过80M的文件是不能在S ...
- 应用 EditPlus 配置 Java 编译环境
此文全文摘抄自: http://jingyan.baidu.com/album/37bce2be3ceef61002f3a208.html?picindex=7,谢啦 应用成功: EditPlus(文 ...
- Android jni 编程2(对基本类型一维整型数组的操作)
参考教程和这位博主的对一维数组的处理,主要包括以下三种类型: //传入一维数组,无返回值 public native void arrayEncode(int[] arr); //传一个一维数组和数组 ...
- bootstrap-标签页
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...