java 对比txt大文件的方法

缘来又是你 2016-03-13 04:05:09
如题,本人比较菜,参考了网上众多方法,现在依然没有找到解决的办法。我要对比的文件很大,是用一个 1G多的txt文件对比多个大文件TXT(含有过G的),找到相同项,之后生成一个含有相同项的txt文件。现在每当我的文件比较大的时候就内存溢出了,有什么办法分片读取,或者多线程提高效率(多线程本人没用过)吗?
求大神 贴出具体的处理代码,感激不尽。若可以 所以分都给你都行。
贴出自己参考网上人修改的代码,现在用2百多M的对比2百M的文件没什么大问题,过G就OVER了。主要是到getText2那个方法的时候 应该也就是读取放到内存的时候 溢出了。 怎么改进呢,或者其他的好方法,
package com.java.test;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class FileCompare {
public static void main(String[] args) throws IOException {

FileCompare c = new FileCompare();
long starTime=System.currentTimeMillis();
List<String> list = new ArrayList<String>();
list.add("C:\\data\\201601_1_2659165.txt");
list.add("C:\\data\\201601_2_7897618.txt");
list.add("C:\\data\\201601_3_6982874.txt");
list.add("C:\\data\\201601_4_5418256.txt");
list.add("C:\\data\201601_5_6757133.txt");
list.add("C:\\data\\201601_6_38000026.txt");
list.add("C:\\data\\201601_7_3806464.txt");
list.add("C:\\data\\201601_8_4820159.txt");
Map map = c.compareFile2("D:/1.txt",list.toArray());
System.out.println("-------->"+map.get("Common"));
// System.out.println("-------->"+map.get("Commonset"));
long endTime=System.currentTimeMillis();
long Time=endTime-starTime;
System.out.println("执行耗费时间:"+Time);

}


/**
* 3.1 对比的第二个为多个
* @param file11 比较文件path
* @param file22 被比较文件数组path
* @return 比较后的信息Map key1:Commonset匹配集合;key2:Common匹配数
*/
public Map compareFile2(String file11,Object[] file22) {
Map resultmap = new HashMap();
File file = new File(file11);
Set fileTextSet = new HashSet();
try {
System.out.println("开始解析第一个("+file11+")");
getText2(file, fileTextSet);//解析第一个txt
System.out.println("解析第一个("+file11+")完毕");
Set resultset = new HashSet();//匹配总集合
int resultCommon = 0;//匹配总数
for(Object file2s:file22){
System.out.println("开始对比file2s:"+file2s.toString());
Set file2TextSet = new HashSet();
File file2 = new File(file2s.toString());
System.out.println("开始解析("+file2s.toString()+")");
getText2(file2, file2TextSet);//解析另一个txt
System.out.println("解析("+file2s.toString()+")对比完毕");
System.out.println("开始匹配"+file2s.toString());
Map re = compareSet2(fileTextSet, file2TextSet);
System.out.println("匹配"+file2s.toString()+"完毕");
Set a = (Set) re.get("Commonset");
int numCommon =(int) re.get("Common");
resultset.addAll(a);//将匹配的集合放入到总集合
resultCommon += numCommon;//将匹配的数量+到总数
}
resultmap.put("Commonset", resultset);
resultmap.put("Common", resultCommon);
return resultmap;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
//3.2
private Map compareSet2(Set textSet, Set StextSet2) {
Map map = new HashMap();
Set commonset = new HashSet();//放入匹配的集合

int numOfCommon = 0, numOfBase = 0, numOfAdap = 0;
for (Iterator iterator = textSet.iterator(); iterator.hasNext();) {
String name = (String) iterator.next();
if (StextSet2.contains(name)) {
System.out.println("common:" + name);//匹配项
commonset.add(name);//匹配项
numOfCommon++;
} else {
// System.out.println("1:" + name);//第一个文件项
}
numOfBase++;
}
for (Iterator iterator = StextSet2.iterator(); iterator.hasNext();) {
String name = (String) iterator.next();
if (!textSet.contains(name)) {
// System.out.println("2:" + name);//第二个文件项
}
numOfAdap++;
}
map.put("Commonset", commonset);//匹配集合
map.put("Common", numOfCommon);//匹配数
map.put("firstFIleNum", numOfBase);//第一个文件数
map.put("SecondFIleNum", numOfAdap);//第二个文件数
System.out.println("Common: " + numOfCommon);//匹配数
System.out.println("1: " + numOfBase);//第一个文件数
System.out.println("2: " + numOfAdap);//第二个文件数
return map;
}
//3.3
private void getText2(File file, Set textSet) throws IOException {
System.out.println("进入到了getText2方法");
BufferedReader br = null;
InputStream is = null;
try {
is = new FileInputStream(file);
br = new BufferedReader(new InputStreamReader(is, "UTF-8"),10*1024*1024);// 用10M的缓冲读取文本文件
String lineStr = null;
while ((lineStr = br.readLine()) != null) {
String text = lineStr.substring(lineStr.indexOf(""));// 按照需求切分
// System.out.println("text:"+text);
textSet.add(text);
}
if (br != null) {
br.close();
}
if (is != null) {
is.close();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null) {
br.close();
}
if (is != null) {
is.close();
}
}
}

/**
* 采用BufferedInputStream方式读取文件行数
* 这个方法没有在这个逻辑里用可以忽略
* @param filename
* @return
* @throws IOException
*/
public int count(String filename) throws IOException {
InputStream is = new BufferedInputStream(new FileInputStream(filename));
byte[] c = new byte[1024];
int count = 0;
int readChars = 0;
while ((readChars = is.read(c)) != -1) {
for (int i = 0; i < readChars; ++i) {
if (c[i] == '\n')
++count;
}
}
is.close();
return count;
}

}


...全文
441 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
缘来又是你 2017-06-27
  • 打赏
  • 举报
回复
已经解决了, 核心的思路是归并算法, 果然 算法才是王道啊
缘来又是你 2016-03-15
  • 打赏
  • 举报
回复
引用 1 楼 bao110908 的回复:
肯定不能直接比了,内存中放不下。参考一下【布隆过滤器】或许能够帮到你。
我网上找到了个分片的方法,得到了索引,可是每一份依然执行的好慢。。。。,因为被对比文件很多 而且也有很大的,每当对比到大文件就狗带了
缘来又是你 2016-03-15
  • 打赏
  • 举报
回复
引用 1 楼 bao110908 的回复:
肯定不能直接比了,内存中放不下。参考一下【布隆过滤器】或许能够帮到你。
我在网上找到了一个将TXT 按字节分片的方法,速度很快http://www.tuicool.com/articles/VBFbA36,结合这个方法拿到的索引位置,差不多将一个较大的TXT文本分成了10份,然后每一份放到集合set中,这样内存貌似开销不是很大了,再用他去对比,但是效率依然超慢。我看了你再 http://bbs.csdn.net/topics/190144112 中的帖子发的方法,参考中,不知道适不适合我说的这个场景,还有你说的布隆 还高大上啊。。。不知道怎么用都。。。
rumlee 2016-03-13
  • 打赏
  • 举报
回复
分段处理啊,
  • 打赏
  • 举报
回复
肯定不能直接比了,内存中放不下。参考一下【布隆过滤器】或许能够帮到你。
内容概要:本文围绕基于蜣螂优化算法(DBO)的无线传感器网络(WSN)覆盖优化问题展开研究,提出了一种创新性的智能优化解决方案,并提供了完整的Matlab代码实现。研究首先分析了传统WSN覆盖优化中存在的覆盖率低、能耗不均等问题,随后引入蜣螂优化算法这一新型群体智能算法,通过模拟蜣螂的生物行为机制,构建了适用于传感器节点部署优化的数学模型。文中详细阐述了算法的设计思路、实现步骤及其在提高网络覆盖率、延长网络生命周期方面的有效性,同时通过仿真实验与其他主流优化算法进行了对比,验证了所提方法的优越性。; 适合人群:具备一定优化算法基础和Matlab编程能力,从事通信工程、物联网、智能优化等相关领域的研究生及科研人员。; 使用场景及目标:①解决无线传感器网络中节点部署不合理导致的覆盖盲区问题;②提升网络整体覆盖性能与资源利用效率;③为智能优化算法在实际工程中的应用提供可复现的研究案例和技术参考。; 阅读建议:建议读者结合文中的Matlab代码进行实践操作,重点关注算法参数设置、适应度函数设计及仿真结果分析部分,同时可尝试将该算法迁移至路径规划、资源调度等其他优化场景中进行拓展研究。
已经博主授权,源码转载自 https://pan.quark.cn/s/a4b39357ea24 在信息技术领域,特别是软件编程行业,微软公司推出的集成开发环境(IDE)Visual Studio,凭借其卓越的功能和广泛的适用范围,成为了众多程序员的常用工具。不过,在实际操作期间,用户可能会遭遇各种挑战,其中一种较为普遍的挑战是“Visual Studio遭遇了异常情况,这或许与某个附加组件有关”。本文将详细研究这一现象的成因、潜在后果以及最终的应对措施。 ### 原因剖析 Visual Studio通过支持多种插件和附加组件来扩展其功能,这些组件通常由第三方开发者设计,旨在为用户提供更多个性化和专业化的工具。然而,这些插件的质量良莠不齐,部分可能未经过充分的测试或与特定版本的Visual Studio存在兼容性难题,从而在执行时引发异常。异常的出现可能源于以下几个因素: 1. **代码缺陷**:若附加组件中的代码存在逻辑问题或资源管理不当,就可能导致运行时异常。 2. **资源竞争**:多个插件同时占用相同的资源(例如内存、文件句柄等),可能会产生资源冲突,进而触发异常。 3. **依赖不匹配**:插件可能需要特定版本的库或框架,如果系统中安装的版本不一致,也可能导致异常。 4. **安全隐患**:部分插件可能存在安全漏洞,一旦被恶意利用,可能会导致更严重的问题,包括但不限于异常崩溃。 ### 后果分析 当Visual Studio遇到由附加组件引发的异常时,不仅会中断当前的工作进程,降低开发效能,还可能带来以下潜在风险: 1. **数据遗失**:若异常发生在保存操作之前,可能会导致未保存的工作内容遗失。 2. **稳定性减弱**:频繁的异常会导致Visual Stud...

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧