栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

RandomAccessFile的一种用法

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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工具能更好的实现随意读写文件?

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/820847.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号