Java多线程读取大文件
前言
今天是五一假期第一天,按理应该是快乐玩耍的日子,但是作为一个北漂到京师的开发人员,实在难想出去那玩耍。好玩的地方比较远,近处又感觉没意思。于是乎,闲着写篇文章,总结下昨天写的程序吧。
昨天下午朋友跟我聊起,他说有个需求,需要把上G的txt文件读取写入到数据库。用普通的io结果自然是OOM了,所以果断用NIO技术。为了提高速度,自然还得用上多线程技术。
接下来就介绍一下实现思路以及相关的知识点。
内容
一、对文件分区
为了充分利用多线程读取,就需要把文件划分成多个区域,供每个线程读取。那么就需要有一个算法来计算出每个线程读取的开始位置和结束位置。那么首先根据配置的线程数和文件的总长度计,算出每个线程平均分配的读取长度。但是有一点,由于文件是纯文本文件,必须按行来处理,如果分割点在某一行中间,那么这一行数据就会被分成两部分,分别由两个线程同时处理,这种情况是不能出现的。所以各个区域的结束点上的字符必须是换行符。第一个区域的开始位置是0,结束位置首先设为(文件长度/线程数),如果结束点位置不是换行符,就只能加1,直到是换行符位置。第一个区域的结束位置有了,自然我们就能求出第二个区域的开始位置了,同理根据上边算法求出第二个区域的结束位置,然后依次类推第三个、第四个......
上边的算法中,第一个区域的结束位置定了,才能有第二个区域的开始位置,第二个区域的结束位置定了,才能有第三个区域的开始位置,依次这么下去。照这种规律,自然地想到的是用递归来解决。(详情看源码)
二、内存文件映射
简单说一下内存文件映射:
- 内存文件映射,简单地说就是将文件映射到内存的某个地址上。
- 要理解内存文件映射,首先得明白普通方式读取文件的流程:
- 首先内存空间分为内核空间和用户空间,在应用程序读取文件时,底层会发起系统调用,由系统调用将数据先读入到内核空间,然后再将数据拷贝到应用程序的用户空间供应用程序使用。这个过程多了一个从内核空间到用户空间拷贝的过程。
- 如果使用内存文件映射,文件会被映射到物理内存的某个地址上(不是数据加载到内存),此时应用程序读取文件的地址就是一个内存地址,而这个内存地址会被映射到了前面说到的物理内存的地址上。应用程序发起读之后,如果数据没有加载,系统调用就会负责把数据从文件加载到这块物理地址。应用程序便可以读取到文件的数据。省去了数据从内核空间到用户空间的拷贝过程。所以速度上也会有所提高。
在我的读取大文件的实现中,就是用了Java的内存映射API,这样我们就可以在要读取某个地址时再将内容加载到内存。不需要一下子全部将内容加载进来。
总结
以上就是我主要用到的思路和一些技术点吧。可能存在某些表达不清楚的地方,望大神勿喷^_^
具体实现请参考代码吧,这里是代码的地址(Java读取大文件)
Java多线程读取大文件的更多相关文章
- Java快速读取大文件
Java快速读取大文件 最近公司服务器监控系统需要做一个东西来分析Java应用程序的日志. 第一步探索: 首先我想到的是使用RandomAccessFile,因为他可以很方便的去获取和设置文件指针,下 ...
- Java高效读取大文件
1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung (http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 ...
- Java高效读取大文件(转)
1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung(http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 读 ...
- java nio 读取大文件
package com.yao.bigfile; import java.io.File; import java.io.IOException; import java.io.RandomAcces ...
- java读取大文件
1 多线程 2 java内存映射读取大文件
- Java 读取大文件方法
需求:实际开发中读取文本文件的需求还是很多,如读取两个系统之间FTP发送文件,读取后保存到数据库中或日志文件的数据库中保存等. 为了测试首先利用数据库SQL生成大数据文件. 规则是 编号|姓名|手机号 ...
- java 分次读取大文件的三种方法
1. java 读取大文件的困难 java 读取文件的一般操作是将文件数据全部读取到内存中,然后再对数据进行操作.例如 Path path = Paths.get("file path&qu ...
- Java读取大文件的高效率实现
1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung (http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 ...
- java读取 500M 以上文件,java读取大文件
java 读取txt,java读取大文件 设置缓存大小BUFFER_SIZE ,Config.tempdatafile是文件地址 来源博客http://yijianfengvip.blog.163.c ...
随机推荐
- 实现Ogre的脚本分离 - 天龙八部的源码分析(一)
目的 在研究天龙八部游戏的源码之时, 发现 Ogre 材质的模板部分被单独放在一个 material 文件之内, 继承模板的其他材质则位于另外的文件, 当我使用Ogre 官方源码, 加载脚本时其不会查 ...
- Android(shape.xml)
shape用以在android设计中定义几何形状,这样简单的效果就不需要以来背景图片.基本的功能如下: <shape xmlns:android="http://schemas.and ...
- 【C语言学习】《C Primer Plus》第8章 字符输入/输出和输入确认
学习总结 1.缓冲区分为完全缓冲区(fully buffered)I/O和行缓冲区(line-buffered)I/O.对完全缓冲输入来说,当缓冲区满的时候会被清空(缓冲区内容发送至其目的地).这类型 ...
- 【源码笔记】Nop定时任务
网站需要定时执行不同的任务,比如清理无效的数据.定时发送mail等,Nop的这个定时任务设计比较好,简单的说就是将所有任务相同的属性持久化,具体的执行通过继承接口来实现. 持久化对象:Schedule ...
- [安卓] 15、用NFC解锁手机并自动打开应用
最近接到一个项目:将手机放到一个带有NFC卡的底座上手机会自动解锁,然后打开相应的应用 本人用:杭州公交通用卡做为NFC卡+Coolpad手机进行试验 效果如下: 1.手机本身带有图案锁,输对图案才能 ...
- [浅学] 1、Node.js尝试_安装&运行第一个helloworld
官网:https://nodejs.org/ 介绍:Node.js® is a platform built on Chrome's JavaScript runtime for easily bui ...
- GLFW初体验
GLFW - 很遗憾,没有找到FW的确切含义,Wiki上没有,GLFW主页也没有.猜测F表示for,W表示Window GLFW是干啥用的? 一个轻量级的,开源的,跨平台的library.支持Open ...
- 细说.NET中的多线程 (五 使用信号量进行同步)
上一节主要介绍了使用锁进行同步,本节主要介绍使用信号量进行同步 使用EventWaitHandle信号量进行同步 EventWaitHandle主要用于实现信号灯机制.信号灯主要用于通知等待的线程.主 ...
- jQuery自动加载更多程序
1.1.1 摘要 现在,我们经常使用的微博.微信或其他应用都有异步加载功能,简而言之,就是我们在刷微博或微信时,移动到界面的顶端或低端后程序通过异步的方式进行加载数据,这种方式加快了数据的加载速度,由 ...
- Nodejs·构建web应用
本篇的内容比较多..... 1 首先是从基本的Nodejs服务方面讲述前后端统一语言在web应用中的作用: 2 然后讲了web中基本的知识,从请求方法到路由.从查询字符串到Cookie和Session ...