RandomAcessFile、MappedByteBuffer和缓冲读/写文件

项目需要进行大文件的读写,调查测试的结果使我决定使用MappedByteBuffer及相关类进行文件的操作,效果不是一般的高。

网上参考资源很多,如下两篇非常不错:

1、花1K内存实现高效I/O的RandomAccessFile类
2、Java中Stream和Memory-mapped File的I/O性能对比
小结:
1、RandomAccessFile本身不带缓冲读写,和FileInputStream、FileOutputStream等一样,直接按字节读写时,性能不可接受;
2、使用MappedByteBuffer读写,固然性能会得到极大提升;其实只要自己处理缓冲,性能都会有非常大的提升,比如以下两种方式(见下记代码)中第一种使用了MappedByteBuffer,第二种自己进行缓冲,对于12M的文件,后者的效率甚至高于前者。
3、BufferedXXXX之类的缓冲流,如果仅使用默认的buffer size,性能不一定最优,要权衡不同情况各种因素设置大小。
package helloword.helloword;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

    }

    public void test() throws IOException {
        /*
         * 测试结果与Buffer size有关
         */
        // 1、使用MappedByteBuffer: 0.7s
        String srcFile = "D://Noname1.txt";
        String destFile = "D://copy.txt";
        RandomAccessFile rafi = new RandomAccessFile(srcFile, "r");
        RandomAccessFile rafo = new RandomAccessFile(destFile, "rw");
        FileChannel fci = rafi.getChannel();
        FileChannel fco = rafo.getChannel();
        long size = fci.size();
        MappedByteBuffer mbbi = fci.map(FileChannel.MapMode.READ_ONLY, 0, size);
        MappedByteBuffer mbbo = fco.map(FileChannel.MapMode.READ_WRITE, 0, size);
        long start = System.currentTimeMillis();
        for (int i = 0; i < size; i++) {
            byte b = mbbi.get(i);
            mbbo.put(i, b);
        }
        fci.close();
        fco.close();
        rafi.close();
        rafo.close();
        System.out.println("Spend: " + (double) (System.currentTimeMillis() - start) / 1000 + "s");

    }

    public void test2() throws IOException {
        // 2、自己处理Buffer(RandomAccessFile): 0.13s
        String srcFile = "D://Noname1.txt";
        String destFile = "D://copy.txt";
        RandomAccessFile rafi = new RandomAccessFile(srcFile, "r");
        RandomAccessFile rafo = new RandomAccessFile(destFile, "rw");

        byte[] buf = new byte[1024 * 8];

        long start = System.currentTimeMillis();

        int c = rafi.read(buf);

        while (c > 0) {
            if (c == buf.length) {
                rafo.write(buf);
            } else {
                rafo.write(buf, 0, c);
            }

            c = rafi.read(buf);
        }
        rafi.close();
        rafo.close();
        System.out.println("Spend: " + (double) (System.currentTimeMillis() - start) / 1000 + "s");

    }

    public void test3() throws IOException {
        // 3、BufferedInputStream&BufferedOutputStream: 3.02s
        String srcFile = "D://Noname1.txt";
        String destFile = "D://copy.txt";
        FileInputStream rafi = new FileInputStream(srcFile);
        FileOutputStream rafo = new FileOutputStream(destFile);

        BufferedInputStream bis = new BufferedInputStream(rafi, 8192);
        BufferedOutputStream bos = new BufferedOutputStream(rafo, 8192);
        long size = rafi.available();

        long start = System.currentTimeMillis();

        for (int i = 0; i < size; i++) {
            byte b = (byte) bis.read();
            bos.write(b);
        }
        rafi.close();
        rafo.close();
        System.out.println("Spend: " + (double) (System.currentTimeMillis() - start) / 1000 + "s");
    }
}
时间: 2024-08-02 23:02:05

RandomAcessFile、MappedByteBuffer和缓冲读/写文件的相关文章

java并发读&写文件

最近在看Brian Goetz 的<<Java并发实战>>,这本书有两个版本,电子工业出版社的译本很糟糕,建议使用机械工业出版社出版出版的书籍. 在看到第三四章的时候突然想到了多线程读写文件,同时遇到一些书中没有的问题 1, 如何保证组合对象的安全性? 2, 如何判断不变性的约束条件 3, 如何不通过synchronized关键字和锁进行同步处理? 下面是一段代码, 用来从source 读取数据,通过多线程写入target文件中 思路: 1, 如何read/write文件? 2,

java读/写文件

读取文件参考:https://blog.csdn.net/weixin_42129373/article/details/82154471 写入文件参考:https://blog.csdn.net/BanketBoy/article/details/86504704 https://www.cnblogs.com/chenpi/p/5498731.html 1 package text; 2 3 import java.io.BufferedReader; 4 import java.io.Bu

Python 文件(读\写)操作

文件(读\写)操作 open()函数,用来打开文件,创建file对象.open(name[,mode[,buffering]])name:要打开的文件mode:是打开文件的模式(读.写.追加)buffering:是否要寄存,默认为0或者False(不寄存),1或True表示寄存(意味着使用内存来代替硬盘,让程序更快,只有使用flush或者close才会更新硬盘上的数据),如果大于1表示寄存区的缓冲大小(单位:字节),如果是负值,表示寄存区为系统默认大小. open函数中模式参数的常用量:r 读模

java创建文本、文件、读文件、写文件

1 package Head18; 2 3 import java.io.BufferedReader; 4 import java.io.File; 5 import java.io.FileNotFoundException; 6 import java.io.FileReader; 7 import java.io.FileWriter; 8 import java.io.IOException; 9 10 public class Mkdirs_FileRW { 11 public st

ubuntukylin基础 chmod 对一个文件的所有者,用户组,其他人分别添加或删除 读 写 执行 的权限

镇场文:       学儒家经世致用,行佛家普度众生,修道家全生保真,悟易理象数通变.以科技光耀善法,成就一良心博客.______________________________________________________________________________________________________ 我的系统:UbuntuKylin 16.04 LTS 64bit step0: 查看指定文件的权限 step1: 减去所有者的 读 写 执行的权限 step2: 查看执行效果

02_Android写xml文件和读xml文件

?? 新建Android项目 编写AndroidManifest.xml,使本Android项目具有单元测试功能和写外设的权限. <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.xmldemo" a

asp.net 文件操作小例子(创建文件夹,读,写,删)

静态生成要在虚拟目录下创建文件夹 来保存生成的页面 那么就要对文件进行操作 一.创建文件夹 using System.IO; string name = "aa"; string path = Server.MapPath("") + "\\" + name; if (Directory.Exists(path)) { Response.Write("<script>alert('文件夹已存在了!');history.go(

Java读取文件 利用MappedByteBuffer进行缓冲

Java读取文件 利用MappedByteBuffer进行缓冲,这样可以保证边读取大文件,边进行处理 package sean; import java.io.ByteArrayInputStream; import java.io.File; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.util.Scann

VB Open 函数详解 打开、关闭、读、写文件

(一)打开和关闭文件      1.顺序文件     打开顺序文件,我们可以使用Open语句.它的格式如下:Open pathname For [Input |Output |Append] As [#]filenumber [Len = buffersize]      说明:     (1)参数pathname 表示要打开的文件名,文件名可以包含有驱动器和目录     (2)Input Output 和Append用于设置顺序文件的打开方式.其中,Input表示从打开的文件中读取数据.以这种