文件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 721B
B. Passwords time limit per test:2 seconds memory limit per test:256 megabytes input:standard input ...
- asp.net权限认证:Windows认证
asp.net权限认证系列 asp.net权限认证:Forms认证 asp.net权限认证:HTTP基本认证(http basic) asp.net权限认证:Windows认证 asp.net权限认证 ...
- java_ 集合
集合类说明及区别Collection├List│├LinkedList│├ArrayList│└Vector│ └Stack└SetMap├Hashtable├HashMap└WeakHashMap ...
- 微信小程序 JS动态修改样式
微信小程序这个坑啊,js动态修改样式,我们并不能用js或者jq 轻轻松松一行代码搞定.或者用removeClass addClass 来修改样式. 以下是一种动态修改样式的方法,原理是绑定数据,然后动 ...
- 获取当前用户的网络状态--iOS
http://m.blog.csdn.net/blog/u014483033/39229417
- c语言中,有符号数位移
#include <stdio.h> int main(void) { unsigned i = 0xcffffff3; long j=0xcffffff3; int k=0xcfffff ...
- HTTP状态码理解
100-199 用于指定客户端应相应的某些动作. 200-299 用于表示请求成功. 300-399 用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息. 400-499 用于指出客户端的错 ...
- 继BAT之后 第四大巨头是谁
中国互联网三大巨头的位置,毫无疑问是属于百度腾讯阿里的,但在它们之后,哪家公司能进巨头之列?京东布局不错,走亚马逊路线:360同时占据传统和移动互联网两大领域入口:小米软硬整合,生态系统完整. 很多人 ...
- 由于java.util.Arrays.asList(...)导致的异常
前言: Collections.toArray()与Arrays.asList() 是Java API提供的友好的相互转换工具,日常开发中用于列表和数组之间的转换非常方便,但今天测试时,发现一下隐藏的 ...
- 架构师之路——里氏替换原则LSP
定义: 如果对每一个对类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有发生变化,那么类型S是类型T的子类型. 内容: 里氏替换原则通 ...