当前位置: 首页 > 编程日记 > 正文

利用java多线程向MongoDB中批量插入静态文件

第一步、开发环境:

win7 64位(注:MongoDb在32位windows上有数量限制(2G),详见官方文档)

    Mongodb3.2

    mongofb_java_driver 3.2.2

第二部、安装mongodb,并开启服务

    略:可参见官方文档

第三部、代码

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;
import org.bson.Document;
import com.mongodb.MongoClient;
import com.mongodb.MongoWriteException;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;/***  created by soarhu 2016/4/21*/public class MongodbBatchInsetUtils {static final int ThreadNum=3;//设置向MongoDb中插入数据的线程数static int ThreadSizeCount = 0;//用于计算子线程完成数static final String HOST = "127.0.0.1";//主机static final int PORT = 27017;//端口    static final String DATABASE_NAME="mydb";//存储数据库名称,如果不存在会自动创建数据库static final String COLLECTION_NAME="md";//存储Collectionpublic static final String DIR = "E:\\targets";//扫描文件路径public static final String FILE_SUFFIX = "html";//扫描文件类型,不设置,默认为所有文件public static final String CHARSET = "UTF-8";//文件处理编码格式public static void main(String[] args) {MongoClient client =new MongoClient(HOST,PORT);MongoDatabase dataBase = client.getDatabase(DATABASE_NAME);MongoCollection<Document> collection = dataBase.getCollection(COLLECTION_NAME);Pool p = new Pool();Produce pro = new Produce(p);Long startTime = System.currentTimeMillis(); new Thread(pro).start();//开启从磁盘读取文件的线程Thread[] th = new Thread[ThreadNum];for(int i=0;i<ThreadNum;i++){//开启向mongoDb写入数据的线程Thread a = new Thread(new Customer(p,collection));a.start();th[i]=a;}boolean res=true;while(res){if(MongodbBatchInsetUtils.ThreadSizeCount==ThreadNum+1){res=false;Long endTime = System.currentTimeMillis();System.out.println("数据写入完成,吸入总数:"+p.hasUploadToDB+",共花费时间约为:"+(endTime-startTime)+"ms\n");for(Thread t:th){t.interrupt();//在子线程将数据写完后,中断子线程。
               }if(null!=client){client.close();//关闭连接collection=null;dataBase=null;} } else {System.out.println("已写入数据:"+p.hasUploadToDB);try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}}}
}//生产者,从磁盘读取数据
class Produce implements Runnable{private Pool pool=null;public Produce(Pool pool){this.pool= pool;}@Overridepublic void run() {getFilesInDir(MongodbBatchInsetUtils.DIR, MongodbBatchInsetUtils.FILE_SUFFIX);MongodbBatchInsetUtils.ThreadSizeCount++;System.out.println("READING FINISHED!!");}//递归读取dir目录中所有以suffix结尾的文件,若不指定文件类型,默认读取所有文件public void getFilesInDir(String dir,String suffix){if(null!=dir && dir.trim().length()>0){File file = new File(dir.trim());if(file.exists() && file.isDirectory()){File[] flist = file.listFiles();if(null!=flist && flist.length>0){for(File f:flist){if(f.isFile()){if(null==suffix|| "".equals(suffix)){pool.putFile(f);}if(null!=suffix &&suffix.trim().length()>0){if(f.getName().endsWith(suffix.trim())){pool.putFile(f);}else{throw new RuntimeException("找不到对应文件类型");}}}else{getFilesInDir(f.getAbsolutePath(),suffix);}}}else{throw new RuntimeException("文件内容为空");}}else{throw new RuntimeException("目录不存在,请检查路径正确性!");}}}
}//消费者,向mongoDb中写数据
class Customer implements Runnable{private Pool pool=null;MongoCollection<Document> collection = null;public Customer(Pool pool,MongoCollection<Document> collection){this.pool = pool;this.collection = collection;}@Overridepublic void run() {while(true){File f = pool.fetchFile();if(null==f){return ;}try {saveToMonGoDb(f);
//                if(pool.hasUploadToDB%1000==0)
//                    System.out.println("已写入数据:"+pool.hasUploadToDB);} catch (MongoWriteException e) {System.out.println("写入数据库异常:"+e.getMessage());return ;}if(pool.getSize()==0){System.out.println(Thread.currentThread().getName()+" :WRITTING FINISHED!!");MongodbBatchInsetUtils.ThreadSizeCount++;}}}//将文件以文件名为id,文件内容为值保存在数据库中private void saveToMonGoDb(File file){String _id = file.getName().substring(0,file.getName().lastIndexOf("."));String content = readFileContext(file, MongodbBatchInsetUtils.CHARSET);Document document = new Document("_id",_id).append("content", content);collection.insertOne(document);}//读取文件内容,以charSet编码处理public static String readFileContext(File file,String charSet)  {StringBuilder sb;BufferedReader reader=null;try {reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), charSet)); String line = null;sb = new StringBuilder();while(null!=(line = reader.readLine())){sb.append(line+"\n");}return sb.toString();}catch (Exception e) {System.out.println("文件读取失败!"+e.getMessage());}finally{try {reader.close();} catch (IOException e) {e.printStackTrace();}}return null;}}//池,缓冲区
class Pool{volatile int size=0;//缓冲区中条目数量volatile int limit =1000;volatile int hasUploadToDB=0;volatile private  List<File> files = new LinkedList<File>();//入栈public  synchronized void putFile(File file){while(files.size()==limit){try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}files.add(file);notifyAll();++size;}//出栈public synchronized File fetchFile(){while(files.size()==0 ){try {this.wait();} catch (InterruptedException e) {return null;}}File file = null;notify();if(files.size()>0){file = files.remove(0);--size;++hasUploadToDB;}return file;}public int getSize(){return this.size;}}

转载于:https://www.cnblogs.com/alienSmoking/p/5422675.html

相关文章:

为啥我从后台查到的值在页面显示的是undefined_再谈一个管理后台列表功能应有的素质...

​大家能看到的这个号第1篇文章《无心朝政&#xff0c;列表功能分析下》就是讲列表功能。虽然当时写的时候特别认真&#xff0c;但基本是围绕“列表功能”这个广泛的词来阐述的。最近在做一个体育赛事赛程的后台管理系统 Match-Schedule&#xff0c;对管理后台列表有更多的体会…

Go语言的错误异常处理机制及其应用

一、背景 在日常编写golang程序或阅读别人的golang代码时&#xff0c;我们总会看到如下的一堆代码块&#xff1a; xx, err func(xx) if err ! nil {//do sth. to tackle this problem }这种经典的显式错误处理方式&#xff0c;在golang开发中几乎无处不在&#xff0c;了解过…

【Win10 应用开发】语音命令与App Service集成

昨天&#xff0c;老周演示了语音命令集成这一高大上功能&#xff0c;今天咱们来点更高级的语音命令。 在昨天的例子中&#xff0c;响应语音命令是需要启动应用程序的&#xff0c;那么如果可以不启动应用程序&#xff0c;就直接在小娜面板上进行交互&#xff0c;是不是会更高大小…

Maya 2022中的硬表面建模技术学习视频教程

Maya 2022中的硬表面建模 信息: 使用正确的拓扑和边流在Maya中建模硬曲面对象。 你会学到什么 硬质表面工具和技术 细分工作流程 边缘流动控制 正确拓扑 材料设置 Studio Lightning 渲染 持续时间16小时30分钟 1280X720 MP4 大小解压后&#xff1a;11.5G 语言&#xff1a;英…

六年级小学python第四讲_python第四讲

列表的排序 升序&#xff1a;从小到大的排序 降序:从大到小的排序 示例&#xff1a; num_list [120,250,11,44,77,45,22,390] num_list.sort() # 升序 - 从小到大 print(num_list) # 对列表本身做了修改 num_list.sort(reverseTrue)#降序 为False#升序 print(num_list) 反转 p…

android之AlertDialog 点击其它区域自己主动消失

遇到一个问题记录下来&#xff0c;在开发中使用了AlertDialog&#xff0c;想点击屏幕其它区域的时候让这个dialog消失&#xff0c;一開始不做不论什么设置&#xff0c;在小米手机能够正常显示&#xff0c;可是在三星中却有问题。后来发现少了一个属性&#xff1a; View dilaogV…

中级实训第一天的自学报告

目录【阅读时间&#xff1a;约10分钟】中级实训第一天的自学报告姓名&#xff1a;隐藏敏感信息 学号&#xff1a;隐藏敏感信息一、Vi/Vim二、Java三、Ant四、Junit【附加】五、SonarQube【附加】六、 编译运行BugRunner七、 总结中级实训第一天的自学报告 姓名&#xff1a;隐藏…

完整的Blender三维课程:素描到三维艺术的初学者

使用Blender创建3D艺术。初级课程 你会学到什么 使用Blender并理解它的界面 创建3D模型 创建您自己的材料 布料仿真、纹理和雕刻 第三种解释的相机法则 照相机景深 灯光设置 渲染 如何使用参考素材进行3D素描和建模&#xff1f;参考镜头也包括在内。 课程中包含所有章节场景文…

VirtualBox: Effective UID is not root

为什么80%的码农都做不了架构师&#xff1f;>>> 桌面上运行virtualbox出错: The virtual machine xp has terminated unexpectedly during startup with exit code 1 (0x1). Effective UID is not root(euid1000 egid482 uid1000 gid482)(rc-10) Please try reinst…

ironpython 教程_「ironpython」VS2017 IronPython做界面

本人开始做毕设了&#xff0c;但老师说工具要有界面&#xff0c;所以就开始找Python做界面的东西……之前做过C#的界面&#xff0c;脱拉拽很快界面就完成了&#xff0c;后来我查了下IronPython是用C#写的python解释器&#xff0c;也可以脱拉拽做界面&#xff0c;于是就开始尝试…

4、jQuery实现的全选、反选和不选功能

2019独角兽企业重金招聘Python工程师标准>>> 这个地址更权威&#xff1a;最好的选择&#xff1a;http://www.sucaihuo.com/js/10.html <html><head><title>TODO supply a title</title><meta charset"UTF-8"><meta name…

构建自己的PHP框架--构建缓存组件(1)

作为一个框架&#xff0c;我们还没有相应的缓存组件&#xff0c;下面我们就来构建我们的缓存组件。 先来定义一下接口&#xff0c;在 src 文件夹下创建 cache 文件夹&#xff0c;在cache文件夹下创建 CacheInterface.php 文件&#xff0c;其中定义 Cache 相应的接口&#xff0c…

基于Golang的CLI 命令行程序开发

基于Golang的CLI 命令行程序开发 【阅读时间&#xff1a;约15分钟】一. CLI 命令行程序概述二. 系统环境&项目介绍&开发准备1.系统环境2.项目介绍3.开发准备三.具体程序设计及Golang代码实现1.selpg的程序结构2.导入的库3.sp_args结构体4.全局变量4.main函数5.process_…

Photoshop创造氛围照片合成视频教程含素材

数百个高分辨率工具和9个完整项目&#xff01; 这个包包含开始创建史诗大气合成所需的一切-超过四个小时的基于项目的深入教程和超过400个合成工具。 大小解压后&#xff1a;10.7G 含课程素材文件 1920X1080 mp4 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机…

java c++的区别_Java语言与C、C++之间的区别?

小伙伴你知道吗&#xff1f;Java是由C开发而来的&#xff0c;并且在当时一直被搁置。随着Java语言的崛起那么Java和C/C有什么不同和相同之处呢&#xff1f;通过上述我们知道那Java前身是C&#xff0c;并且保留了C的大部分内容&#xff0c;其编程方式也类似于C。但Java的句法更清…

Android编程获取网络连接状态及调用网络配置界面

获取网络连接状态 随着3G和Wifi的推广&#xff0c;越来越多的Android应用程序需要调用网络资源&#xff0c;检测网络连接状态也就成为网络应用程序所必备的功能。 Android平台提供了ConnectivityManager 类&#xff0c;用于网络连接状态的检测。 Android开发文档这样描述Connec…

学习在Unity中创建一个动作RPG游戏

游戏开发变得简单。使用Unity学习C#并创建您自己的动作角色扮演游戏&#xff01; 你会学到什么 学习C#&#xff0c;一种现代通用的编程语言。 了解Unity中2D发展的能力。 发展强大的和可移植的解决问题的技能。 了解游戏开发流程。 了解面向对象编程在实践中是如何工作的。 Le…

python数组对应元素相乘_python的几种矩阵相乘的公式详解

1. 同线性代数中矩阵乘法的定义&#xff1a; np.dot() np.dot(A, B)&#xff1a;对于二维矩阵&#xff0c;计算真正意义上的矩阵乘积&#xff0c;同线性代数中矩阵乘法的定义。对于一维矩阵&#xff0c;计算两者的内积。见如下Python代码&#xff1a; import numpy as np # 2-D…

c#属性中的get和set属性

get是给属性赋值&#xff0c;set是取属性的值。 get、set用法&#xff1a; 一是隐藏组件或类内部的真是成员&#xff1b; 二是用来建立约束的&#xff0c;比如&#xff0c;实现“有我没你”这种约束&#xff1b; 三是用来响应属性变化事件&#xff0c;当属性变化是做某事&#…

基于Golang的监听读取配置文件的程序包开发——simpleConfig_v1

基于Golang的监听&读取配置文件的程序包开发——simpleConfig_v1 【阅读时间&#xff1a;约10分钟】 一、配置文件概述二、系统环境&项目介绍1.系统环境2.项目的任务要求三、具体程序设计及Golang代码实现1. 数据结构2. init函数模块3.listen函数模块4.watch函数模块四…

如何在Mac环境下搭建svn服务器端环境

为什么80%的码农都做不了架构师&#xff1f;>>> 在Windows环境中&#xff0c;我们一般使用TortoiseSVN来搭建svn环境。在Mac环境下&#xff0c;由于Mac自带了svn的服务器端和客户端功能&#xff0c;所以我们可以在不装任何第三方软件的前提下使用svn功能&#xff0…

kitbash贫民区三维场景模型 Kitbash3d – Favelas

参观临时城市中心 想象一下新兴的后世界末日城市中心&#xff0c;这里有大量的临时住所、建筑群、小屋、道具和固定装置。用一系列非常详细的废弃街区快速构建您的场景&#xff0c;并用波纹铁、水箱、折叠椅和劣质电线进一步修饰它们。从足球场到摇摇欲坠的码头&#xff0c;每一…

python编程代码示例_python编程线性回归代码示例

用python进行线性回归分析非常方便&#xff0c;有现成的库可以使用比如&#xff1a;numpy.linalog.lstsq例子、scipy.stats.linregress例子、pandas.ols例子等。 不过本文使用sklearn库的linear_model.LinearRegression&#xff0c;支持任意维度&#xff0c;非常好用。 一、二维…

单例模式的两种实现方式对比:DCL (double check idiom)双重检查 和 lazy initialization holder class(静态内部类)...

首先这两种方式都是延迟初始化机制&#xff0c;就是当要用到的时候再去初始化。 但是Effective Java书中说过&#xff1a;除非绝对必要&#xff0c;否则就不要这么做。 1. DCL (double checked locking&#xff09;双重检查&#xff1a; 如果出于性能的考虑而需要对实例域(注意…

【golang程序包推荐分享】go-ini、viper、godoc

【golang程序包推荐&分享】go-ini、viper、godoc一、go-ini1.程序包简介2.下载安装3.简单使用【截取自官网】二、viper1.程序包简介2.下载安装3.简单使用三、godoc1.程序包简介2.下载安装3.简单使用一、go-ini 1.程序包简介 ini 是常用的配置文件格式&#xff0c;而go-in…

Request To JavaBean(请求对象转换为JavaBean对象)

背景: 经常要从request等对象取出值来赋入bean中&#xff0c;如果不用MVC框架的绑定功能的话,麻烦 一 参考资料 1 http://jc-dreaming.iteye.com/blog/563893 2 http://www.iteye.com/topic/76043 3 http://xubindehao.iteye.com/blog/754807 4 http://javafenger.iteye.com/b…

在Substance Designer中创建砖墙视频教程

学习在Substance Designer中创建复杂材料的高级技术。 如果你想进入游戏行业&#xff0c;想学习如何创建高质量的纹理和学习物质设计&#xff0c;那么这个课程是给你的。 我设计了这个课程&#xff0c;从一开始就带你&#xff0c;教你我用来创建AAA纹理的3个步骤:图案&#xff…

python requests 动态加载_python requests 高级用法

HTTP动词 Requests 提供了几乎所有HTTP动词的功能&#xff1a;GET、OPTIONS、HEAD、POST、PUT、PATCH、DELETE。以下内容为使用 Requests 中的这些动词以及 Github API 提供了详细示例。 我将从最常使用的动词 GET 开始。HTTP GET 是一个幂等方法&#xff0c;从给定的 URL 返回…

redis配置开机启动

2019独角兽企业重金招聘Python工程师标准>>> 一、下载安装 去http://download.redis.io/releases/现在最新的redis版本解压 tar zxvf xxx.tar.gz编译进入到解压开的目录&#xff0c;执行&#xff1a;make && make install(可选)添加到bin目录cp redis-serve…

Docker exec命令详细使用指南

Docker exec命令是Docker提供的一个强大工具,用于在正在运行的容器中执行命令。本文将详细介绍Docker exec命令的用法和示例,帮助大家更好地理解和使用这个命令。Docker是一种流行的容器化平台,允许我们在容器中运行应用程序。有时候,在容器内执行命令可以帮助我们调试、排查问题或进行其他操作。这就是Docker exec命令发挥作用的时候。本文详细介绍了Docker exec命令的用法和示例。