java 大文本随机指定位置读取

大家知道java RandomAccessFile类 提供了光标定位到文本指定位置 实现随机读取,对于大文本性能很高,但是jdk没有提供定位到指定位置后找到行头再开始读取的这样一个功能,这里手写一个,实现光标定位到指定位置后,定位到行头,并一次读取指定大小的数据,数据完整不会有乱码。

public class FileRandomRead {

    /**
     * 
     * 对于一个超大文本文件,文件中每一行数据都是一条有效数据。每行数据大小小于1KB
     * 
     * 现在要随机从文件某个位置开始,每次读取不少于128KB的数据。
     * 
     * 要保证读取的内容中必须包含开始位置,并且开始、与结束部分,是完成的一行数据。
     *
     * */
    public static void main(String[] args) throws IOException {
        File file = new File("d:/javatest/random.txt");
        long randomLocation = (long) (Math.random() * file.length());
        //unit test
        randomLocation = 17;
        List<String> list = randomReadLine(file, randomLocation);
        list.stream().forEach(System.out::println);
    }

    public static List<String> randomReadLine(File file, long pos) throws IOException {
        @Cleanup
        final RandomAccessFile f = new RandomAccessFile(file, "r");
        String separator = System.getProperty("line.separator");
        f.seek(pos);
        int c = f.read();
        //判断是否换行,寻找行开头
        while (c != 10 && --pos != -1) {
            f.seek(pos);
            c = f.read();
        }
        //纠正位置
        f.seek(++pos);
        List<String> lineList = new ArrayList<>();
        String line;
        while ((line = f.readLine()) != null) {
            //RandomAccessFile会将编码格式转换成 ISO-8859-1,所以此处要转回来
            lineList.add(new String(line.getBytes("ISO-8859-1"), "utf-8"));
            String content = String.join(separator, lineList);
            //业务要求最少读取128kb
            if (content.getBytes().length >= 128 * 1000) {
                break;
            }
        }
        return lineList;
    }

}

如果对你有帮助,别忘了给文章点赞呦~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值