RandomAccessFile的一种用法

       现在有这么一个场景,需要每天将数据库中的XXX表符合要求的明细写入文件,并且文件第一行需要写入总笔数,XXX表总数据量是千万级,查询数据库必须分页。

       A方案是先在数据库count(*)统计总笔数,写入文件,再做分页查询追加到文件中;

       B方案是先分页查询数据库,写入临时文件,边写边统计总笔数;最后将总笔数写入正式文件,再用通道(Channel): java.nio.channels,将临时文件内容追加到正式文件的总笔数之后;

       C方案是利用RandomAccessFile,网上有很多向文件指定行插入内容的实现,但是都需要将指针后的内容缓存下来,后面再追加写入。

       A方案弊端:count(*)在表数据很大的情况下耗时较长,影响数据库性能;

       B方案弊端:反复读写文件,代码实现较为复杂,但是Channel在复制大文件时,效率非常快,100MB左右的文件,经测试基本上是秒级完成。

       C方案弊端:如果是插入第一行,就是现在这个场景,那么他需要缓存整个文件到内存,那还不如直接查询所有数据,不分页,直接查看结果集长度;

      根据现在这个场景,思考了下。RandomAccessFile可以这么用:

预先判断写入第一行的数据大概长度是多少。

比如现在这个场景,表数据就算到亿级,总笔数长度无非就是9位数。

可以在B方案的基础上,第一行写入10位空字符串,换行后写入明细,不用通道,

最后用一下代码实现向第一行插入总笔数即可,

public static void insert(String filePath, long pos, String str)throws IOException {
    RandomAccessFile raf=null;
    try {
        // 以读写的方式打开一个RandomAccessFile对象
        raf = new RandomAccessFile(new File(filePath), "rw");
        //把文件记录指针定位到pos位置
        raf.seek(pos);
         //追加需要插入的内容
        raf.write(str.getBytes());
     }catch (Exception e){
        throw  e;
     }finally {
        raf.close();
}
}

有的网上博客会这么介绍RandomAccessFile:不能向文件的指定位置插入内容,如果直接将文件记录指针移动到中间某位置后开始输出,则新输出的内容会覆盖文件原有的内容,如果需要向指定位置插入内容,程序需要先把插入点后面的内容写入缓存区,等把需要插入的数据写入到文件后,再将缓存区的内容追加到文件后面。

如果不仔细阅读可能会理解为:新写入的会覆盖掉后面所有的内容,实际上是写入的数据有多长覆盖多长。

所以可以预留一定长度的空字符串,java实现向指定位置插入一些内容。

但是这样的局限性和弊端是显而易见的,希望有大佬能提供什么更好的基于JDK的方案。

至于java调shell什么的不在讨论范围内。

完全由java代码实现,或者有没有什么开源的IO工具能更好的实现随意读写文件?

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值