用MappedByteBuffer写大文件

在search了很多的有关文章,没有找到用MappedByteBuffer写大文件的具体例子.
大部分都是代码类似于:
[code="java"]
MappedByteBuffer raf = fc.map(MapMode.READ_WRITE, 0, fc.size());
[/code]
或是
MappedByteBuffer raf = fc.map(MapMode.READ_WRITE, 0, someHardCode);

[b]需求是这样的: 文件开始并不存在, 并且文件最后到底是多大我也不清楚.[/b]

我的代码如下:

[code]
public static void test2() throws Exception {
//先将上次文件删除
new File("D:/test2.tmp").delete();
RandomAccessFile raf1 = new RandomAccessFile("D:/test2.tmp","rw");
int mapsize = 1024*100;//100K
FileChannel fc = raf1.getChannel();
MappedByteBuffer raf = fc.map(MapMode.READ_WRITE, 0, mapsize);

    byte[] b1 = new byte[]{'a','b','c','d','e','f','g','h'};
    byte[] utfstr = "this is a test".getBytes("UTF-8");

    long s1 = System.currentTimeMillis();
    for(int i=0;i<10000000;i++){//写一千万次, 

//在循环内部, 会发生 java.nio.BufferOverflowException 异常 !!!!!!
raf.put(b1);
raf.putInt(i);
raf.putInt(i+1);

        raf.put(utfstr);
        raf.put((byte)'\n');
    }
    long d1 = System.currentTimeMillis() - s1;
    fc.close();
    raf1.close();
    System.out.println("spent time1="+(d1/1000));
}

[/code]

望有同学指定一下: 是否 MappedByteBuffer 并不适合这种 不断地 append 的写入方式, 只适合大小已经固定的文件的原来内容的改写?

如果也适合的话, 麻烦请个示例代码! 谢谢!

5个回答

[code="java"] long cout = 0;

for (int i = 0; i < 100000; i++) {// 写一千万次,

// 在循环内部, 会发生 java.nio.BufferOverflowException 异常 !!!!!!

if (raf.remaining() < 1024) {

cout += raf.position();

raf = fc.map(MapMode.READ_WRITE, cout, mapsize);

    }  
    raf.put(b1);  

    raf.put(utfstr);  
    raf.put((byte) '\n');  
}  [/code]

注意map超过文件的长度,会使得文件变大

[code="java"] int mapsize = 1024*100;//100K

FileChannel fc = raf1.getChannel();

MappedByteBuffer raf = fc.map(MapMode.READ_WRITE, 0, mapsize); [/code]

这里是否是只映射了100k?
写数据超过100k了吧

MappedByteBuffer是为了不一次将大文件载入内存,而只映射其中的一部分。
当数据超过了原映射大小时,可以向后偏移映射应该可以,但是需要计算已经写入的字节数

如果需要一直在文件尾部添加数据,可以如下:
[code="java"] File file = new File("1.tmp");
FileOutputStream fos = new FileOutputStream(file, true);
ObjectOutputStream ois = new ObjectOutputStream(fos);
byte[] b1 = new byte[]{'a','b','c','d','e','f','g','h'};

byte[] utfstr = "this is a test".getBytes("UTF-8");

    for (int i = 0; i < 10000000; i++) {// 写一千万次,
        ois.write(b1);
        ois.writeInt(i);
        ois.writeInt(i + 1);

        ois.write(utfstr);
        ois.write((byte) '\n');
    }[/code]

[code="java"] for (int i = 0; i < loop; i++) {// 写一千万次,
if (raf.remaining() < 1024) {
raf = fc.map(MapMode.READ_WRITE, raf.position(), mapsize);
}
raf.put(b1);
raf.putInt(i);
raf.putInt(i + 1);

        raf.put(utfstr);
        raf.put((byte) '\n');
    }[/code]

不知道有没有更好的办法

[code="java"] if (raf.remaining() < 1024) {
mapsize += mapsize;
raf = fc.map(MapMode.READ_WRITE, raf.position(), mapsize);
}[/code]

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐