- 浏览: 253360 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
pshaoyi:
连接创建没问题,在执行的时候就报错了。Caused by: c ...
jdbc连接池简单封装 -
imbangbang:
中文乱码,没有解决掉
Java实现Zip压缩与解压(解决中文乱码问题) -
chjy1983:
麻烦也发份给我,chl_82@126.com,谢谢!
Java实现Zip压缩与解压(解决中文乱码问题) -
jidacwj:
楼主写的这个有问题呀首先,多线程分割文件第45行,我尝试打印每 ...
Java 大文件读取排序 -
www6wzk:
非常好的学习例子,十分感谢!
Jbpm工作流实例—报销申请
需求:
csv文件中存在千万级数据,需要按照某一列进行排序
比如
1,royzhou1985@163.com,13752468532,123,1
1,royzhou1985@183.com,13752465532,123,1
1,royzhou1985@173.com,13752463532,123,1
要求可以按照其中某一列,比如邮件地址或者手机号码排序。
实现:
为了不导致内存溢出,每次读取一定数量的记录,比如10W行记录。使用Java API Collections.sort()排序,然后写到一个临时文件。 这样就可以将大文件拆分成很多个排序了的小文件.
然后打开这些小文件,全部读取一行,获取最小的值,然后从那个文件再读取一行,循环判断直到所有文件读取结束。
问题:
性能较差,合成大文件的时候需要做很多次比较。
改进:
分割文件可以用多线程,讲读取到的10W行记录在线程中排序处理。
合成文件?
代码实现:
csv文件中存在千万级数据,需要按照某一列进行排序
比如
1,royzhou1985@163.com,13752468532,123,1
1,royzhou1985@183.com,13752465532,123,1
1,royzhou1985@173.com,13752463532,123,1
要求可以按照其中某一列,比如邮件地址或者手机号码排序。
实现:
为了不导致内存溢出,每次读取一定数量的记录,比如10W行记录。使用Java API Collections.sort()排序,然后写到一个临时文件。 这样就可以将大文件拆分成很多个排序了的小文件.
然后打开这些小文件,全部读取一行,获取最小的值,然后从那个文件再读取一行,循环判断直到所有文件读取结束。
问题:
性能较差,合成大文件的时候需要做很多次比较。
改进:
分割文件可以用多线程,讲读取到的10W行记录在线程中排序处理。
合成文件?
代码实现:
package com.royzhou.sort; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import com.roy.zhou.util.SysConfig; public class FileSorter { public int sort(String fileName, LineProcessor lineProcessor) throws InterruptedException, IOException { int index = split(fileName, lineProcessor); int totalCount = merge(fileName, index, lineProcessor); return totalCount; } public int split(String fileName, LineProcessor lineProcessor) throws InterruptedException, IOException { int fileIndex = 0; BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(); ThreadPoolExecutor pool = new ThreadPoolExecutor(SysConfig.THREAD_NUMBER, SysConfig.THREAD_NUMBER, 600, TimeUnit.SECONDS, workQueue); BufferedReader br = null; int row = 0; String sLine = null; String sKey = null; List<SortedData> sList = new ArrayList<SortedData>(); //LineProcessor lineProcessor = new CSVLineProcessor(SysConfig.KEY_INDEX); br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName))); while((sLine=br.readLine())!=null) { sKey = lineProcessor.process(sLine); sList.add(new SortedData(sKey, sLine, br)); row++; if(row!=0 && row%SysConfig.BATCH_ROW_COUNT==0) { new FileSplitController(pool, workQueue, sList, fileName, fileIndex).dispatchTask(); sList = new ArrayList<SortedData>(); fileIndex++; } } /** * check whether there is still records to be processed */ if(sList.size()>0) { new FileSplitController(pool, workQueue, sList, fileName, fileIndex).dispatchTask(); fileIndex++; } while(workQueue.size()>1) { Thread.sleep(5000); } pool.shutdown(); /** * if all task still not finish, sleep 5 seconds and check again */ while(!pool.isTerminated()) { pool.awaitTermination(5, TimeUnit.SECONDS); } return fileIndex; } public int merge(String fileName, int index, LineProcessor lineProcessor) throws IOException { int totalCount = 0; BufferedWriter bw = null; BufferedReader[] fileReaders = new BufferedReader[index]; List<SortedData> sortedDatas = new ArrayList<SortedData>(index); File[] tempFiles = new File[index]; String iFilePath = null; String outputFile = null; String sLine = null; String sKey = null; for(int i=0; i<index; i++) { iFilePath = fileName + ".tmp" + i; tempFiles[i] = new File(iFilePath); fileReaders[i] = new BufferedReader(new InputStreamReader(new FileInputStream(iFilePath))); sLine = fileReaders[i].readLine(); sKey = lineProcessor.process(sLine); sortedDatas.add(new SortedData(sKey, sLine, fileReaders[i])); } outputFile = fileName + ".sorted"; bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile))); SortedData smallestData = null; String smallestKey = null; String smallestContent = null; String tempKey = null; String tempContent = null; BufferedReader tempReader = null; while(true) { Collections.sort(sortedDatas); smallestData = sortedDatas.get(0); smallestKey = smallestData.getKey(); if(smallestKey==null || "".equals(smallestKey)) { break; } smallestContent = smallestData.getContent(); tempReader = smallestData.getFileReader(); bw.write(smallestContent + "\n"); totalCount++; tempContent = tempReader.readLine(); tempKey = lineProcessor.process(tempContent); sortedDatas.set(0, new SortedData(tempKey, tempContent, tempReader)); } bw.flush(); bw.close(); for(int i=0; i<index; i++) { fileReaders[i].close(); tempFiles[i].delete(); } System.out.println(totalCount); return totalCount; } }
- sort.zip (6.7 KB)
- 下载次数: 154
评论
2 楼
jidacwj
2014-04-13
楼主写的这个有问题呀
首先,多线程分割文件第45行,我尝试打印每个线程的启动与结束时间,结果并不是并行执行的:
线程0开始时间:2014-04-13 22:08:05
耗时:1min0s640ms
线程0结束时间:2014-04-13 22:09:06
线程1开始时间:2014-04-13 22:09:06
耗时:46s632ms
线程1结束时间:2014-04-13 22:09:52
2线程,总耗时:耗时:1min47s518ms
这是为什么呢???!
另外有个建议:
第100行,没必要每次都进行排序,对100000条排序也挺费时间的。只要遍历一遍,找出最小的那条就行。速度能快一倍多。
首先,多线程分割文件第45行,我尝试打印每个线程的启动与结束时间,结果并不是并行执行的:
线程0开始时间:2014-04-13 22:08:05
耗时:1min0s640ms
线程0结束时间:2014-04-13 22:09:06
线程1开始时间:2014-04-13 22:09:06
耗时:46s632ms
线程1结束时间:2014-04-13 22:09:52
2线程,总耗时:耗时:1min47s518ms
这是为什么呢???!
另外有个建议:
第100行,没必要每次都进行排序,对100000条排序也挺费时间的。只要遍历一遍,找出最小的那条就行。速度能快一倍多。
1 楼
caidezhi655
2012-03-26
茫茫互联网,这样都能搜到你的博客
发表评论
-
Mybatis3
2012-01-08 15:07 964看了一下Mybatis3,很简洁,不错,符合一贯的原则。 -
断网情况下主机系统与VMWare虚拟系统建立网络连接
2011-03-07 13:52 1671电脑不插网线设置主机系统与VMWare中linux系统 ... -
Oracle 9i10g编程艺术
2010-12-08 23:41 1070Oracle 9i10g编程艺术 -
SWT And JFace
2010-12-01 21:29 864The_Definitive_Guide_to_SWT_and ... -
SWT 定时器 update UI
2010-11-30 17:00 1861SWT如果涉及到线程中的数据互访,在一个线程中的触发事性中再去 ... -
Log4j XML 配置方式
2010-11-14 13:00 1545Log4j xml 配置文件log4j.xml[默认读取的文件 ... -
ThreadPool 线程池的使用
2010-10-20 21:41 7489import java.util.concurrent.B ... -
Oracle
2010-05-29 22:26 2492最近很有兴趣研究Oracle,今天把Oracle10g ... -
JArgp Command Line Argument Processor
2010-05-12 21:02 890http://sourceforge.net/projects ... -
Java 反射与内省
2009-09-27 22:52 3447一、java反射机制 JAVA反 ... -
分页工具类Page
2009-09-26 16:10 5817public class Page { public ... -
dom4j
2009-07-22 11:52 1104DOM4J是dom4j.org出品的一个开源XML解析 ... -
Javamail 详解
2009-07-21 22:17 2807最近研究JBPM的mail node节点,使用时老是发不出邮件 ... -
proxool数据连接池总结
2009-07-10 21:41 14697数据库连接池总结----Proxool 1、所需jar包: ... -
通过url下载文件HttpURLConnection
2009-07-08 15:48 17255import java.io.*; import jav ... -
web.xml配置五个有用的过滤器
2009-07-01 14:34 3006一、使浏览器不缓存页面的过滤器 Java代码 im ... -
Tomcat 配置JNDI数据源总结
2009-04-24 09:41 2039JNDI是J2EE中一个很重要的标准,通常我们是在J2EE编程 ... -
关于web.xml中的load-on-startup作用
2009-04-19 11:51 2947load-on-startup 元素在web应用启动的时候指定 ... -
Struts2学习笔记
2009-04-18 09:55 1371包括下面内容: 一、Struts2简介.doc 二、Stru ... -
使用模板方法设计模式、策略模式 处理DAO中的增删改查
2009-03-11 00:10 4004摸板方法(Template Me ...
相关推荐
在Java编程中,处理大文件并进行多字段排序是一项挑战性的任务,特别是在内存有限的情况下。以下将详细讲解如何实现这个目标。 首先,我们要理解大文件排序的基本原理。当文件太大无法一次性加载到内存时,我们需要...
在Java编程中,读取文件、对数据进行排序并重新写入文件是常见的操作,尤其在数据处理和分析场景中。下面将详细讲解这个过程,包括相关知识点和具体实现。 首先,我们需要导入Java的`java.io`包,该包包含了处理...
在Java编程中,对文件夹中的文件进行排序是一项常见的任务,尤其在处理大量数据或进行自动化操作时。这里我们将深入探讨如何使用Java实现文件按时间、大小等属性进行排序的功能。 首先,我们要引入`java.io.File`类...
Java 对大数据量文件内容的多线程读取和排序 在处理大数据量文件内容时,多线程读取和排序是非常重要的。下面我们将讨论如何使用 Java 对大数据量文件内容进行多线程读取和排序。 首先,我们需要生成一个随机的...
Java 对大数据量文件内容的多线程读取和排序是非常复杂的任务,涉及到多个方面的技术,包括文件读取、多线程处理、排序算法等。本文将对该问题进行详细的分析和解决方案。 问题描述 生成一个随机的文本文件,其中...
Java GUI成绩录入与排序文件读取是一个典型的桌面应用程序开发示例,主要涉及到Java Swing或JavaFX库用于构建图形用户界面,以及文件I/O操作来处理数据的存储和检索。在这个项目中,用户可以通过一个简单的界面输入...
这个名为"JAVA设计文本文件读取倒序排序"的项目,利用NetBeans IDE,实现了读取文本文件内容并进行倒序排序的功能,同时也提供了保存处理结果的能力。在这个过程中,涉及到的关键知识点包括: 1. **Java I/O流**:...
本文将详细介绍如何在Java中实现对大数据量文件内容的多线程读取和排序。 首先,理解多线程的概念是至关重要的。线程是程序执行的最小单元,每个线程都有自己的程序计数器、虚拟机栈、本地方法栈和一部分堆内存。...
在Java中,文件读取是通过`java.io`包中的类来实现的。本例中用到了`BufferedReader`和`FileReader`。 - **BufferedReader**:提供了一个方便的接口用于读取文本文件中的字符数据。它具有从输入流中读取文本的功能...
这是通过使用 FileReader 和 BufferedReader 读取大文件,然后将其写入到多个小文件中实现的。 ### 2. 文件写入 文件写入是指将数据写入到文件中。在 Java 中,可以使用 Java.IO 包中的 FileWriter 和 ...
在"java集合排序及文件读取.rar"这个压缩包中,我们很可能会找到关于如何在Java中对集合进行排序以及如何读取文件的示例代码。让我们详细探讨这些关键知识点。 **Java集合排序** Java集合框架包括接口如`List`、`...
综上所述,Java大文件IP统计涉及的主要知识点有:Java文件I/O,流式处理,IP地址的处理与比较,数据结构(如HashMap和TreeMap)的选择,以及可能的并发和分布式计算。通过这些技术,我们可以高效地处理大文件中的IP...
有文件大小为1G的一个文件,文件每行存储的为URL及其访问次数,例如/api/auth/login 2 ,计算出访问次数最多的前5个URL和其访问次数,每行的URL可能重复,计算内存限制10M。 === 内含解题思路、测试结果截图、可运行...
sqlitFileDate方法使用FileReader和BufferedReader来读取大数据文件,并使用LinkedList来存储文件流对象和BufferedWriter对象,然后将每个小文件的数据写入到对应的文件中。 在写入和切分文件操作完成后,程序使用...
本课程着重讲解了四个核心概念:文件读写、递归、数组排序以及单体工厂模式。这些知识点都是Java开发者日常工作中不可或缺的部分。 首先,我们来探讨文件读写。在Java中,文件操作主要依赖于I/O(Input/Output)流...
在Java编程中,文件读取、数组操作、选择排序以及二分查找是常见的编程任务,它们涉及了IO流、数据结构和算法等多个方面。以下是这些知识点的详细解释: 1. **文件读取**:Java提供了丰富的IO流类库用于读取文件。...
此段代码展示了基本的文件读取过程,但是原文件中的部分代码似乎尝试进行更复杂的数据处理,包括数据解析、计算和排序。这部分代码涉及到了数据的结构化存储(如使用`List`和`Map`),以及数学运算和排序算法。 ###...
读取一个文件中的整数,并将它们从小到大排序,最后输出排序后到另一个文件中
在实际应用中,Java归并外排序适用于大数据处理场景,如大数据分析、数据库索引构建等。由于其稳定性和效率,尤其是在处理无法一次性加载到内存的数据集时,归并外排序是理想的选择。 总结起来,Java归并外排序是...