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地址访问图片,只用相对路径访问时,在发布网站的时候,将上传图片的目标文件夹,包含在项目中再发布即可.
随机推荐
- P1008 对齐输出
题目描述 读入三个整数,按每个整数占8个字符的宽度,右对齐输出它们. 输入格式 输入的一行包含三个整数 \(a,b,c(1 \le a,b,c \le 10^6)\) . 输出格式 输出一行包含三个整 ...
- tensorflow在文本处理中的使用——Word2Vec预测
代码来源于:tensorflow机器学习实战指南(曾益强 译,2017年9月)——第七章:自然语言处理 代码地址:https://github.com/nfmcclure/tensorflow-coo ...
- Vue与React比较
与React 相似: (1)虚拟DOM(Virtual DOM) 虚拟DOM的诞生是基于:改变真实的DOM状态远比改变一个JS对象的花销要大的多. 虚拟DOM是一个映射真实DOM的JS对象,当有变化产 ...
- 让Word Add-in For MediaWiki支持Word 2013
1.下载并安装Word Add-in For MediaWiki https://www.microsoft.com/en-us/download/details.aspx?id=12298 2.在“ ...
- linux下文件的一些文件颜色的含义
红色---->代表压缩文件 红色闪烁---->代表链接文件有问题 黄色---->代表设备文件 深蓝色---->代表目录 浅蓝色----->代表链接文件 绿色----> ...
- tcp短连接和长连接
1. TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,连接的建立是需要三次 ...
- 利用pandas、Ipython来简化数据分析过程
最近小爬我为了提升数据分析这块儿的技能,学习了pandas库作者Wes Mckinney的数据分析经典书籍<利用Python进行数据分析>,受益良多!里面涉及到Python语言基础.还有编 ...
- 0011 开发者工具(chrome)
此工具是我们的必备工具,以后代码出了问题 我们首先第一反应就是: "按F12"或者是 "shift+ctrl+i" 打开 开发者工具. 菜单: 右击网页空白出- ...
- .NET Core 3 WPF MVVM框架 Prism系列之命令
本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的命令的用法 一.创建DelegateCommand命令 我们在上一篇.NET Core 3 WPF MVVM框架 Prism系列之 ...
- 【题解】AcWing 110. 防晒(普及题)
[题解]AcWing 110. 防晒(普及题) AcWing 110. 防晒 你没有用过的全新OJ 嘿嘿水水题. 题目就是一维坐标轴上给定多个线段,给定多个点,点在线段上造成贡献,点可以重复,问最大贡 ...