ForkJoin统计文件夹中包含关键词的数量
2018-06-09总结:
ForkJoin确实可以很快速的去解析文件并统计关键词的数量,但是如果文件过大就会出现内存溢出,是否可以通过虚拟内存方式解决内存溢出的问题呢?
package com.oxygen.forkjoin.model; import java.util.List; /** * 文档 * @author renguanyu * */ public class Document { private List<String> lines; public Document(List<String> lines) { super(); this.lines = lines; } public List<String> getLines() { return lines; } public void setLines(List<String> lines) { this.lines = lines; } }
package com.oxygen.forkjoin.model; import java.util.List; /** * 文件夹 * @author renguanyu * */ public class Folder { private List<Folder> subFolders; private List<Document> documents; public Folder(List<Folder> subFolders, List<Document> documents) { this.subFolders = subFolders; this.documents = documents; } public List<Folder> getSubFolders() { return subFolders; } public void setSubFolders(List<Folder> subFolders) { this.subFolders = subFolders; } public List<Document> getDocuments() { return documents; } public void setDocuments(List<Document> documents) { this.documents = documents; } }
package com.oxygen.forkjoin.service; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import com.oxygen.forkjoin.model.Document; /** * 文档服务 * @author renguanyu * */ public class DocumentService { /** * 读取文件中所以数据 * @param file 文件 * @return 文档 */ public static Document fromFile(File file) { List<String> lines = new ArrayList<>(); try(BufferedReader reader = new BufferedReader(new FileReader(file))) { String line = reader.readLine(); while (line != null) { lines.add(line); line = reader.readLine(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return new Document(lines); } }
package com.oxygen.forkjoin.service; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ForkJoinPool; import com.oxygen.forkjoin.model.Document; import com.oxygen.forkjoin.model.Folder; import com.oxygen.forkjoin.task.FolderSearchTask; /** * 文件夹服务 * @author renguanyu * */ public class FolderService{ /** * 递归查询文件夹中所有的数据 * 1.在内存中建立文件夹的结构 * 2.把数据都加载到这个结构中,方便下一步计算 * @param dir 文件夹 * @return 文件夹 */ public static Folder fromDirectory(File dir) { List<Document> documents = new ArrayList<>(); List<Folder> subFolders = new ArrayList<>(); for (File entry : dir.listFiles()) { if (entry.isDirectory()) { subFolders.add(FolderService.fromDirectory(entry)); } else { documents.add(DocumentService.fromFile(entry)); } } return new Folder(subFolders, documents); } /** * 获取关键词总数 * @param targetFolder 目标文件夹 * @param keyword 关键词 * @throws IOException */ public static long getKeywordTotal(String targetFolder, String keyword) { ForkJoinPool forkJoinPool = new ForkJoinPool(); //把文件夹中的数据加载到内存中,我这个文件夹中就一个日志文件 File dir = new File(targetFolder); Folder folder = FolderService.fromDirectory(dir); //创建一个搜索任务 FolderSearchTask task = new FolderSearchTask(folder, keyword); //开始执行fork/join任务 long counts = forkJoinPool.invoke(task); return counts; } }
package com.oxygen.forkjoin.task; import java.util.List; import java.util.concurrent.RecursiveTask; import com.oxygen.forkjoin.model.Document; /** * 文档搜索任务 * @author renguanyu * */ public class DocumentSearchTask extends RecursiveTask<Long> { private static final long serialVersionUID = 1L; private Document document; private String searchedWord; public DocumentSearchTask(Document document, String searchedWord) { super(); this.document = document; this.searchedWord = searchedWord; } @Override protected Long compute() { long count = 0; List<String> lines = document.getLines(); for (String line : lines) { String[] words = line.trim().split("(\\s|\\p{Punct})+"); for (String word : words) { if (searchedWord.equals(word)) { count = count + 1; } } } return count; } }
package com.oxygen.forkjoin.task; import java.util.ArrayList; import java.util.List; import java.util.concurrent.RecursiveTask; import com.oxygen.forkjoin.model.Document; import com.oxygen.forkjoin.model.Folder; /** * 文件夹搜索任务 * @author renguanyu * */ public class FolderSearchTask extends RecursiveTask<Long> { private static final long serialVersionUID = 1L; private Folder folder; private String searchedWord; public FolderSearchTask(Folder folder, String searchedWord) { super(); this.folder = folder; this.searchedWord = searchedWord; } //计算方法 @Override protected Long compute() { long count = 0L; List<RecursiveTask<Long>> forks = new ArrayList<>(); //获取文件夹下的子文件夹 for (Folder subFolder : folder.getSubFolders()) { //递归文件夹搜索任务 FolderSearchTask task = new FolderSearchTask(subFolder, searchedWord); //把任务添加到分叉列表,用于合并任务 forks.add(task); //放到工作队列中 task.fork(); } //获取文件夹下的文档 for (Document document : folder.getDocuments()) { DocumentSearchTask task = new DocumentSearchTask(document, searchedWord); //把任务添加到分叉列表,用于合并任务 forks.add(task); //放到工作队列中 task.fork(); } //合并工作队列中各个线程计算结果的值 for (RecursiveTask<Long> task : forks) { count = count + task.join(); } return count; } }
package com.oxygen.forkjoin.test; import java.io.IOException; import com.oxygen.forkjoin.service.FolderService; /** * 测试程序 * @author renguanyu * */ public class MainTest { public static void main(String[] args) throws IOException { long startTime = System.currentTimeMillis(); long counts = FolderService.getKeywordTotal("C:\\test\\logs\\", "null"); long stopTime = System.currentTimeMillis(); long completeTime = stopTime - startTime; System.out.println(counts + " , fork / join search took " + completeTime + "ms"); } }
ForkJoin统计文件夹中包含关键词的数量的更多相关文章
- Path,Files巩固,题目:从键盘接收两个文件夹路径,把其中一个文件夹中(包含内容)拷贝到另一个文件夹中
这个题目用传统的File,InputStream可以做,但是如果用Files,Path类做,虽然思路上会困难一些,但是代码简洁了很多,以下是代码: import java.io.IOException ...
- 使用.NET统计文件夹中文件总数
软件下载: http://hovertree.com/h/bjaf/hwqtjwjs.htm 截图: 使用方法:点击按钮,选择文件夹,就可以显示文件夹中包含的文件总数. 这个项目包含在HoverTre ...
- 【linux】统计文件夹中文件行数
统计当前目录下,排除venv目录,剩余所有py文件的行数 wc -l `find -path ./venv -prune -o -name '*py'`
- java基础 File 递归删除文件夹中所有文件文件夹 目录(包含子目录)下的.java文件复制到e:/abc文件夹中, 并统计java文件的个数
File 递归删除文件夹中所有文件文件夹 package com.swift.kuozhan; import java.io.File; import java.util.Scanner; /*键盘录 ...
- 用字符流实现每个文件夹中创建包含所有文件信息的readme.txt
package com.readme; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; i ...
- 用C语言实现统计一个文件夹中各种文件的比例
<UNIX环境高级编程>中的程序清单4-7就介绍了如何实现递归地统计某个目录下面的文件!我刚开始看过它的代码后,觉得照着敲太没意思了,所以就合上书自己写了一遍!为此还写了一篇博文,这是博文 ...
- (文档)Shader.Find (在编译时,只包含那些使用中的shader或位置在"Resources"文件夹中shader)
Shader.Find 查找 static function Find (name : string) : Shader Description描述 Finds a shader with the g ...
- 【原】Mac下统计任意文件夹中代码行数的工
[链接][原]Mac下统计任意文件夹中代码行数的工http://www.cnblogs.com/wengzilin/p/4580646.html
- .net网站上传图片换电脑不显示 当不用网站的IP地址访问图片,只用相对路径访问时,在发布网站的时候,将上传图片的目标文件夹,包含在项目中再发布即可。
.net网站上传图片换电脑不显示 当不用网站的IP地址访问图片,只用相对路径访问时,在发布网站的时候,将上传图片的目标文件夹,包含在项目中再发布即可.
随机推荐
- H3C 主动方式建立连接过程
- 【u104】组合数
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 组合数C(N, K)表示了N个数字不重复地选取K个作组合的方案数. C(N, K) = N!/(N-M ...
- 被孟加拉题吊打的ACM考试
https://codeforces.com/gym/101864 题目并不难 B 考虑新加入的线段和之前线段有交的个数 总数-不交的,不交的:右端点在[l,r]左边,左端点在[l,r]右边的. 维护 ...
- rabbitmq template发送的消息中,Date类型字段比当前时间晚了8小时
前言 前一阵开发过程遇到的问题,用的rabbitmq template发送消息,消息body里的时间是比当前时间少了8小时的,这种一看就是时区问题了. 就说说为什么出现吧. 之前的配置是这样的: @B ...
- Github Pages 无法调用 node_modules 文件夹的解决方案
今天写一个demo,用npm安装的前端库,然后想在github的pages上展示出来 发布到github后,发现node_modules文件夹下的js无法调用 google解决方案:新增一个名字为.n ...
- 学习Java第二周
这是学习java的第二周,又这样不知不觉的结束了 上周想要学习的这一周也都做到了,可是觉得进度有些慢了,学习了: 1. 接口和抽象类: 2. 集合与数组: 3. 方法的定义: 4. 递归算法: 5.对 ...
- mybatis精讲(六)--二级缓存
目录 简介 配置 源码 CachingExecutor 自定义二级缓存 # 加入战队 微信公众号 简介 上一章节我们简单了解了二级缓存的配置.今天我们详细分析下二级缓存以及为什么不建议使用二级缓存. ...
- pandas数据分析小知识点(一)
最近工作上,小爬经常需要用python做一些关于excel数据分析的事情,显然,从性能和拓展性的角度出发,使用pandas.numpy是比vba更好的选择.因为pandas能提供诸如SQL的很多查找. ...
- 网络状态诊断工具——netstat命令
netstat命令可以用来查询整个系统的网络状态.百度百科的定义如下: Netstat的定义是: Netstat是在内核中访问网络连接状态及其相关信息的程序,它能提供TCP连接,TCP和UDP监听,进 ...
- $SP15637\ GNYR04H\ -\ Mr\ Youngs\ Picture\ Permutations$
传送门 Description 杨先生希望为他的班级拍照.学生将排成一行,每行不超过后面的行,并且行的左端对齐.例如,可以安排12名学生排列(从后到前)5,3,3和1名学生. X X X X X X ...