第一步、开发环境:

    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

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

  1. delay在java中有什么用_DelayQueue怎么在Java多线程并发开发中使用

    DelayQueue怎么在Java多线程并发开发中使用 发布时间:2020-12-05 17:29:31 来源:亿速云 阅读:56 作者:Leah 这篇文章给大家介绍DelayQueue怎么在Java ...

  2. 利用java多线程技术和图像显示技术来完成动画设计。

    利用java多线程技术和图像显示技术来完成动画设计. package p2;import java.applet.Applet; import java.awt.Graphics; import ja ...

  3. 向Excel中批量插入图片,自动排版

    一.安装软件 向Excel中批量插入图片,需要用到一个工具"E灵",您只需百度搜索"罗刚君E灵" 5个字即可找到下载地址,也可以在以下网站找到: http:// ...

  4. 重复最多字符次数java_利用Java实现求字符串中出现次数最多的字符及次数

    利用Java实现求字符串中出现次数最多的字符及次数 发布时间:2020-11-12 16:57:24 来源:亿速云 阅读:108 作者:Leah 这篇文章将为大家详细讲解有关利用Java实现求字符串中 ...

  5. SQL语句中批量插入

    SQL语句中批量插入 1.介绍说明 ​ 在程序中需要同时插入多条数据的写法,其中mysql和oracle两种写法存在一些差异. oracle数据库 insert into <tableName& ...

  6. 【工具与环境】Excel中批量插入行

    Excel中批量插入行 一.插入一行 二.插入多行 三.插入列同理 一.插入一行 在使用EXCEL时一定会遇到这样的问题--那就是插入行,右键→插入 二.插入多行 如何插入多行呢?有人也许会说&quo ...

  7. excel怎么批量插行_excel中批量插入对应名称的图片,你用了1天,同事2分钟就搞定了...

    Hello.大家好,昨天有粉丝留言说如何在excel中批量插入图片?他有很多张命名好的图片,想要在excel中根据姓名在旁边插入对应的图片,自己一个一个做了好久,有没有快速的方法,当然有了,今天就跟大 ...

  8. WORD2007中无法插入CMG文件

    WORD2007中无法插入CMG文件 提示:导入此文件出错 依据 KB 2479871 中所描述: 从 Microsoft 安全公告 MS10-105 开始,出于安全考虑,在默认设置下,包括 CGM ...

  9. 群晖自动删除重复文件_在群晖中批量删除重复文件(零基础手把手图文)

    在群晖中批量删除重复文件(零基础手把手图文) 2020-03-26 14:51:01 24点赞 229收藏 39评论 小编注:此篇文章来自即可瓜分10万金币,周边好礼达标就有,邀新任务奖励无上限,点击 ...

最新文章

  1. 达人眼中的WINCE网络驱动
  2. js 日期对象 31 号 setMonth 的锅
  3. 软件工程导论团队项目
  4. 【我想进大厂】Redis夺命连环11问
  5. 五分钟,手撸一个Spring容器!
  6. 吓人!普京最新Deepfake视频来了,MIT现场伪造实时采访
  7. c++ int8_t转int_c专题之指针-----什么是指针?
  8. Redis的安装配置与介绍(Windows版)
  9. 大部分程序员只会写三年代码?
  10. CSS从零开始(1)--CSS基础语法
  11. [EMNLP18]用序列标注来进行成分句法分析
  12. 查看系统信息msinfo32工具的使用
  13. 元素出现>强调>再消失的动画制作【PPT动画】
  14. 读书笔记——晶体管电路设计
  15. 阿里云移动测试-远程真机篇
  16. Odoo与浪潮合资研发PS Cloud之如何处理序列号
  17. 计算机一级考试题电子表格,2017计算机一级Excel模拟考试题
  18. 多线程、并发/并行、自定义线程类、线程安全、守护线程、定时器、线程状态、线程池
  19. c语言编写“输入密码,是否登录成功的程序”
  20. 攻受音测试软件,我的攻受小瓶子测试入口

热门文章

  1. 你听说过反摩尔定律吗?
  2. Python3:ImportError: No module named 'compiler.ast'
  3. Conversion error:Jekyll::Converters::Scss encountered an error while converting css/main.scss
  4. Spring Data JPA 五分钟快速入门和实践
  5. 基于javaGUI的文档识别工具制作
  6. 华为计算平台MDC810发布量产
  7. MegEngine 框架设计
  8. MindSpore API编程概述
  9. 处理器嵌入室内校正数字音频平台
  10. 基于NVIDIA GPUs的深度学习训练新优化