前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 读取大文件,你了解多少呢

Java 读取大文件,你了解多少呢

作者头像
格姗知识圈
发布2019-07-19 15:21:53
1.9K0
发布2019-07-19 15:21:53
举报
文章被收录于专栏:格姗知识圈格姗知识圈

问:使用 Java 如何读取大文件,你有什么建议或者经验?

答:我们平常读取一般文件都是将文件数据直接全部读取到内存中进行操作的,这种做法对于小文件是没有问题的,但对于稍大一些的文件就会抛出 OOM 异常,所以我们应该把大文件分成多个子区域分多次读取。

思路一:文件流边读边用,使用文件流的 read() 方法每次读取指定长度的数据到内存中,具体样板代码如下。

代码语言:javascript
复制
//BufferedReader类同
BufferedInputStream reader = new BufferedInputStream(new FileInputStream("big.txt"), 8192);
int bytes = -1;
do {
    byte[] tmpArray = new byte[8192];
    bytes = reader.read(tmpArray);
    if (bytes != -1) {
        //做事情
    }
} while(bytes > 0);
reader.close();

思路二:对大文件建立 NIO 的 FileChannel,每次调用 read() 方法时会先将文件数据读取到已分配固定长度的 java.nio.ByteBuffer 中,接着从中获取读取的数据。这种用 NIO 通道的方法比传统文件流读取理论上要快一点,具体样板代码如下。

代码语言:javascript
复制
FileInputStream fileIn = new FileInputStream("big.txt");
ByteBuffer byteBuf = ByteBuffer.allocate(65535);
FileChannel fileChannel = fileIn.getChannel();
int bytes = -1;
do {
    bytes = fileChannel.read(byteBuf);
    if (bytes != -1) {
        byte[] array = new byte[bytes];
        byteBuf.flip();
        byteBuf.get(array);
        byteBuf.clear();
        //拿array做事情
        System.out.println(new String(array));
    }
} while (bytes > 0);
byteBuf.clear();
fileChannel.close();
fileIn.close();

思路三:内存文件映射,就是把文件内容映射到虚拟内存的一块区域中,从而可以直接操作内存当中的数据而无需每次都通过 I/O 去物理硬盘读取文件,这种方式可以提高速度,具体样板代码如下。

代码语言:javascript
复制
FileInputStream fileIn = new FileInputStream("big.txt");
FileChannel fileChannel = fileIn.getChannel();
MappedByteBuffer mappedBuf = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());
boolean end = false;
do {
    int limit = mappedBuf.limit();
    int position = mappedBuf.position();
    if (position >= limit) {
        end = true;
    }

    int maxSize = 2048;
    if (limit - position < maxSize) {
        maxSize = limit - position;
    }
    byte[] array = new byte[maxSize];
    mappedBuf.get(array);
    //拿array搞事情
    System.out.println(new String(array));
} while (!end);
mappedBuf.clear();
fileChannel.close();
fileIn.close();

思路四:使用 RandomAccessFile 的 seek() 方法进行分块读写操作,具体实现非常简单,和普通文件操作一样,不过还是推荐 JDK 1.4 NIO 的内存映射文件。

您还有什么推荐呢?

推荐阅读

点击文字即可阅读

免费简单高效的下载工具

知道这个插件的人,都是PPT高手

Excel导入数据库方式

你真的知道Java内存模型是什么吗

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-09-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 格姗知识圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档