前言

  今天是五一假期第一天,按理应该是快乐玩耍的日子,但是作为一个北漂到京师的开发人员,实在难想出去那玩耍。好玩的地方比较远,近处又感觉没意思。于是乎,闲着写篇文章,总结下昨天写的程序吧。

  昨天下午朋友跟我聊起,他说有个需求,需要把上G的txt文件读取写入到数据库。用普通的io结果自然是OOM了,所以果断用NIO技术。为了提高速度,自然还得用上多线程技术。

  接下来就介绍一下实现思路以及相关的知识点。

内容

     一、对文件分区

        为了充分利用多线程读取,就需要把文件划分成多个区域,供每个线程读取。那么就需要有一个算法来计算出每个线程读取的开始位置和结束位置。那么首先根据配置的线程数和文件的总长度计,算出每个线程平均分配的读取长度。但是有一点,由于文件是纯文本文件,必须按行来处理,如果分割点在某一行中间,那么这一行数据就会被分成两部分,分别由两个线程同时处理,这种情况是不能出现的。所以各个区域的结束点上的字符必须是换行符。第一个区域的开始位置是0,结束位置首先设为(文件长度/线程数),如果结束点位置不是换行符,就只能加1,直到是换行符位置。第一个区域的结束位置有了,自然我们就能求出第二个区域的开始位置了,同理根据上边算法求出第二个区域的结束位置,然后依次类推第三个、第四个......

        上边的算法中,第一个区域的结束位置定了,才能有第二个区域的开始位置,第二个区域的结束位置定了,才能有第三个区域的开始位置,依次这么下去。照这种规律,自然地想到的是用递归来解决。(详情看源码

    二、内存文件映射

      简单说一下内存文件映射:

    内存文件映射,简单地说就是将文件映射到内存的某个地址上。
要理解内存文件映射,首先得明白普通方式读取文件的流程:
首先内存空间分为内核空间和用户空间,在应用程序读取文件时,底层会发起系统调用,由系统调用将数据先读入到内核空间,然后再将数据拷贝到应用程序的用户空间供应用程序使用。这个过程多了一个从内核空间到用户空间拷贝的过程。 如果使用内存文件映射,文件会被映射到物理内存的某个地址上(不是数据加载到内存),此时应用程序读取文件的地址就是一个内存地址,而这个内存地址会被映射到了前面说到的物理内存的地址上。应用程序发起读之后,如果数据没有加载,系统调用就会负责把数据从文件加载到这块物理地址。应用程序便可以读取到文件的数据。省去了数据从内核空间到用户空间的拷贝过程。所以速度上也会有所提高。

      在我的读取大文件的实现中,就是用了Java的内存映射API,这样我们就可以在要读取某个地址时再将内容加载到内存。不需要一下子全部将内容加载进来。

总结

  以上就是我主要用到的思路和一些技术点吧。可能存在某些表达不清楚的地方,望大神勿喷^_^

  具体实现请参考代码吧,这里是代码的地址(Java读取大文件

  

        

Java多线程读取大文件的更多相关文章

  1. Java快速读取大文件

    Java快速读取大文件 最近公司服务器监控系统需要做一个东西来分析Java应用程序的日志. 第一步探索: 首先我想到的是使用RandomAccessFile,因为他可以很方便的去获取和设置文件指针,下 ...

  2. Java高效读取大文件

    1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung (http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 ...

  3. Java高效读取大文件(转)

    1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung(http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 读 ...

  4. java nio 读取大文件

    package com.yao.bigfile; import java.io.File; import java.io.IOException; import java.io.RandomAcces ...

  5. java读取大文件

    1  多线程 2  java内存映射读取大文件

  6. Java 读取大文件方法

    需求:实际开发中读取文本文件的需求还是很多,如读取两个系统之间FTP发送文件,读取后保存到数据库中或日志文件的数据库中保存等. 为了测试首先利用数据库SQL生成大数据文件. 规则是 编号|姓名|手机号 ...

  7. java 分次读取大文件的三种方法

    1. java 读取大文件的困难 java 读取文件的一般操作是将文件数据全部读取到内存中,然后再对数据进行操作.例如 Path path = Paths.get("file path&qu ...

  8. Java读取大文件的高效率实现

    1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung (http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 ...

  9. java读取 500M 以上文件,java读取大文件

    java 读取txt,java读取大文件 设置缓存大小BUFFER_SIZE ,Config.tempdatafile是文件地址 来源博客http://yijianfengvip.blog.163.c ...

随机推荐

  1. QQ在线客服设置

    QQ在线客服设置 1.客户在添加QQ在线客服后,需要让用户在线不需要添加为好友就能在线对话,一般默认设置下会显示"您需要添加对方为好友+才能给对方发送会话消息",具体解决方法如下: ...

  2. JAVA学习博客---2015-7

    @Updata 2015.7.17  开始熟悉API.WPS首字母自动大写,有的没有加#编号的,其实方法首字母不是大写例如Char charAt 实际上是char charAt.当然骆驼写法charA ...

  3. javascript event兼容性随笔

    一.前言 function ConvertEvent(e, element) { var event = e || window.event; var resultEvent = { event: e ...

  4. Hasor-Core v0.0.4 & Web v0.0.3 发布

    “Hasor是一款开源的 Java 应用开发框架.它是围绕 Guice 为核心创建的一系列模块组合而成.使用Hasor 会加快软件软件开发效率并降低开发成本.目前 Hasor包含了 Hasor-Cor ...

  5. 软将工程课设day1与day2

    在稍迟的时候,收集了三份用户体验,自己编辑整理之后上交于组. 和老师确定了一下每日的工作流程与需要提交的任务. 与组讨论了软件优化方向,包括整理收集到的“反馈信息”.“额外需求信息”.“体验信息”.

  6. Ubuntu Desktop安装及桌面美化(修复图片)

    Ubuntu Desktop安装及桌面美化 1   开篇概述 本 系统的文章主要是讲互联网方向的开发主题.根据目前主流互联网公司的技术架构,Linux是必不可少的.对于一直习惯于在Windows下工作 ...

  7. Linux date命令

    命令概述 date命令可以用来设置和显示系统当前时间,特别是在有一些Shell命令里面用到date命令来做日期的不同的显示,所以该命令也是非常需要掌握的一个命令. 语法 date [OPTION].. ...

  8. 剑英陪你玩转图形学(五)focus

    很久没来和大家交流业务(zhuangbi)水平了,最近实在是很忙,报名了小游戏大赛,一点时间都抽不出,已经坑了. 今天抓紧时间和大家介绍一个小效果: 新手引导的时候,我们会需要一种全屏幕黑掉,只有一个 ...

  9. Unity3D热更新全书-脚本(四) 用C#LightEvil搭建实际开发使用的脚本框架

    C#LightEvil之前提供了很多和Unity结合的例子,都是采用把脚本文件放置在StreamingAssets中的方法. 这样可以利用Unity的特性,放在这个目录中的CS文件会被编译器编译,我们 ...

  10. Unity3D热更新全书-脚本(一) 初识脚本

    开篇之前还是要先说明,这是一份给经验并不丰富的程序员阅读的文字. 有需求.有疑惑,往下看. 第一个问题什么是脚本?程序和脚本如何区分?我们给Unity编写的组件是程序还是脚本? 这些问题本文无意去解答 ...