在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 的写入方式, 只适合大小已经固定的文件的原来内容的改写?
如果也适合的话, 麻烦请个示例代码! 谢谢!
[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]