前言

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

  昨天下午朋友跟我聊起,他说有个需求,需要把上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. testMarkDown

    title: git常用命令 date: 2015-10-27 10:28:25 categories: git tags: git 添加 SSH 公钥 Windows 平台中,可以使用 Git Ba ...

  2. 本人讲课时录制的Android应用开发技术教学视频

    网盘地址:http://yun.baidu.com/pcloud/album/info?query_uk=1963923831&album_id=3523786484935252365 本人讲 ...

  3. [ASE]sprint2 总结 & sprint3计划

    第二个sprint半圆满的结束了, 经历了四周之后我们将整个的框架搭建好,并且能够正常的游戏对战,破坏场景,聊天…… 但是正如老师所述,缺乏亮点. 不过大家都是第一次做,完全把他当成一个工程来一点一点 ...

  4. Hibernate自动创建表

    只要在hibernate.cfg.xml添加这句话,就可以自动生成数据表 <property name="hibernate.hbm2ddl.auto">update& ...

  5. 解剖SQLSERVER 第十三篇 Integers在行压缩和页压缩里的存储格式揭秘(译)

    解剖SQLSERVER 第十三篇    Integers在行压缩和页压缩里的存储格式揭秘(译) http://improve.dk/the-anatomy-of-row-amp-page-compre ...

  6. 【面试必备】javascript操作DOM元素

    前言 时间过的真快,不知不觉就到年底了.问问自己,这一年你对自己的工作满意吗? 评价标准是什么呢?当然是马云的那两条准则了:钱给到了吗?干的爽吗?如果答案都是no,那么,你准备好跳槽了吗? 为了应对年 ...

  7. Weibo用户地图

    1.1.1 摘要 现在,许多应用都提供地理位置定位的功能,只要用户开放他们的位置信息就可以实现定位了,今天我们将创建一个基于Google 地图的微博用户地图,这里我们将通过Weibo API获取微博用 ...

  8. Linux C/C++的编译

    以前在Linux上面编译过C,但是没有编译过C++,今天用到了,就稍微学习了一下. 简单的介绍 linux 中最重要的编译工具是 GCC.GCC 是 GNU 的 C 和 C++ 编译器.实际上,GCC ...

  9. HTML、CSS部分

    要点:对Web标准的理解.浏览器差异.CSS基本功:布局.盒子模型.选择器优先级及使用.HTML5.CSS3.移动端开发 技术等 1.Doctype作用? 严格模式与混杂模式-如何触发这两种模式,区分 ...

  10. VS2013 好用的插件

    切换到vs2013上有些时间了,以下是我个人认为比较好的插件. Resharper 神器中的神器,提升编码效率的第一神器,附带提高编码能力:除去臃肿的体积,堪称完美: Productivity Pow ...