描述

最近遇到问题需要将较大的bson文件(MongoDB导出的二进制json文件)按文档(记录)进行切分,网上这方面的资料实在太少,弄了一天多终于达到了基本要求(还不知道有没有BUG)

代码

package splitbson;

import java.io.*;
import java.util.Scanner; /**
* 每条文档的前四个字节表示该文档的字节数,因此只需要读取4个字节数,计算该文档大小。然后用字节流读取即可。
*/
public class SplitBsonUtils {
// 输入流
private static BufferedInputStream bis;
// 输出结果文件的命名编号
private static int fileNameCount = 1;
// 带缓冲区的输出流
private static BufferedOutputStream bos;
// 记录当前文件已写文档(记录)数
private static int documentCount = 0; /**
* 切分bson文件
*
* @param sourceFilePath 源bson文件
* @param fileDocumentNum 每个文件的文档数
* @param targetFilePath 目标文件目录
*/
public static void splitBson(String sourceFilePath, int fileDocumentNum, String targetFilePath) {
if (fileDocumentNum < 0) fileDocumentNum = 100;
try {
// 构建输入流
bis = new BufferedInputStream(new FileInputStream(sourceFilePath));
File dir = new File(targetFilePath);
if (!dir.exists()) {
dir.mkdir();
}
// 构建可缓冲的输出流
bos = new BufferedOutputStream(new FileOutputStream(targetFilePath + "/file" + fileNameCount++ + ".bson", true));
// 获取下一条记录的字节数
int documentSize = getSize(sourceFilePath);
// 减4是因为getSize方法已经读写了四个字节
byte[] arr = new byte[documentSize - 4];
// 开始读源bson文件
while (bis.read(arr) != -1) {
// 写入到新的文件
bos.write(arr);
documentCount++;
// 判断当前文件记录数是否达到自定义文档数
if (documentCount == fileDocumentNum) {
// 创建新的输出流
bos = new BufferedOutputStream(new FileOutputStream(targetFilePath + "/file" + fileNameCount++ + ".bson", true));
documentCount = 0;
}
documentSize = getSize(sourceFilePath);
// 表示已经到了文件结尾
if (documentSize == -1) break;
arr = new byte[documentSize - 4];
}
bos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bis.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} /**
* 获取源bson文件正被读取文档的字节数
*
* @param filePath
* @return
*/
public static int getSize(String filePath) {
byte[] arr = new byte[4];
int size = 0;
try {
bis.read(arr);
size = byte2DecStr(arr);
if (size - 4 < 0) return -1;
bos.write(arr);
} catch (IOException e) {
e.printStackTrace();
}
return size;
} /**
* byte数组转换成十进制字符串
*
* @param b
* @return
*/
public static int byte2DecStr(byte[] b) {
String stmp = "";
StringBuilder sb = new StringBuilder("");
for (int n = b.length - 1; n >= 0; n--) {
stmp = Integer.toHexString(b[n] & 0xFF);
sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
}
return Integer.parseInt(sb.toString(), 16);
} public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请传入三个参数进行bson文件的切分:");
System.out.println("1. 原bson文件绝对路径(无需引号),如:E:/ld_FamilySearch_detail.bson");
String sourceFilePath = scanner.nextLine();
System.out.println("2. 切分后每个文件所要存储的文档(记录)条数,如:100");
int fileDocumentNum = scanner.nextInt();
scanner.nextLine();
System.out.println("3. 切分后文件存储的目录(无需引号),如:E:/result");
String targetFilePath = scanner.nextLine();
System.out.println(sourceFilePath + fileDocumentNum + targetFilePath);
System.out.println("正在进行切分...");
long start = System.currentTimeMillis();
splitBson(sourceFilePath, fileDocumentNum, targetFilePath);
long end = System.currentTimeMillis();
System.out.println("切分完成!共耗时:" + (end - start) + "毫秒");
}
}

bson文件的切分的更多相关文章

  1. 通过 bsondump 命令工具 解析备份产生的bson文件

    bsondump命令是将BSON格式的文件转换为可读性更强的文件格式,例如转为为JSON 格式的文档,bsondump默认转换为json格式的文档. 当通过mongodump命令进行备份时,如果有参数 ...

  2. Python将mongodb导出的bson文件转为字典对象

    Python将mongodb导出的bson文件转为字典对象 安装bson包, sudo pip install bson 示例 # 解决编码问题 import sys reload(sys) sys. ...

  3. MongoDB导入bson文件(元数据),mongorestore命令行方式导入

    MongoDB导入bson文件(元数据),mongorestore命令行方式导入 不推荐使用MongoDB Compass等图形化数据库管理软件,例如MongoDB Compass只能导入json和c ...

  4. MongoDB从bson文件中恢复数据

    首先需要到mangodb的安装目录的bin下面找到mongorestore.exe WIN10系统MongoDB安装目录bin文件夹下没有mongorestore.exe 先下载工具  https:/ ...

  5. 如何将mongodb bson文件转成json文件

    使用mongodb自带的命令 bsondump collection.bson > collection.json

  6. MongoDB导入文件夹(内含json和bson文件)

    1. 使用mongo命令将数据库删除: mongo命令: use db_name; db.dropDatabase() 2. 导入(指定文件夹)数据: linux命令: mongorestore -d ...

  7. hadoop拾遗(一)---- 避免切分map文件

    有些程序可能不希望文件被切分,而是用一个mapper完整处理每一个输入文件.例如,检查一个文件中所有记录是否有序,一个简单的方法是顺序扫描第一条记录并并比较后一条记录是否比前一条要小.如果将它实现为一 ...

  8. sql脚本长度限制及linux下文件切分

    无意翻出以前笔记,切分sql文件,每10万条加一个commit.半天都想不起来应用的场景,能想起来的再加上查的资料记录一下. 在Oracle数据库中,频繁的commit会引起大量Redo Log的物理 ...

  9. [Linux] 随机切分文件内容

    1.从原文件中随机选出若干行 可以直接用shuf命令就可以完成: $ shuf -n source.txt > target.txt shuf命令的说明: $ shuf --help Usage ...

随机推荐

  1. 系统优化怎么做-SQL优化

    大家好,这里是「聊聊系统优化 」,并在下列地址同步更新 博客园:http://www.cnblogs.com/changsong/ 知乎专栏:https://zhuanlan.zhihu.com/yo ...

  2. LeetCodee 105. Construct Binary Tree from Preorder and Inorder Traversal

    问题重述: 问题求解: 我们换一组比较有代表性的样例, 对于上图的树来说, index: 0 1 2 3 4 5 6 先序遍历为: 中序遍历为: 5同理,右子树也是如此.这样不难看出本题应该用递归方法 ...

  3. lock free

    #include <thread> #include <iostream> #include <mutex> #include <atomic> #in ...

  4. 前端String转json

    1.data = eval("("+data+")");2.JSON.parse(data);

  5. 论反向ajax

    在讨论反向ajax之前,说一下我大二写的一个聊天程序,通过前端ajax不断向服务器发送请求(通过http连接),服务器进行一次数据库查询,然后返回结果,断开与服务器的链接(绝大部分都是无用的结果)来维 ...

  6. ubuntu下的数据库和python存储库安装——MySQL,MongoDB,Redis

    MySQL 的安装 sudo apt-get updatesudo apt-get install -y mysql-server mysql-client 启动.关闭和重启MySQL 服务的命令如下 ...

  7. Jupyter Notebook的魔法

    在腾讯云上搭建了一个Jupyter Notebook 还是很好用的, 这里总结了一些看到的小技巧及快捷键使得我们更加快捷的完成工作. Notebook 与 Vim 有些类似,有两种键盘输入模式,即命令 ...

  8. linux 通过 openconnect 来连接学校内网

    参考 http://xingda1989.iteye.com/blog/1969908 https://blog.csdn.net/edin_blackpoint/article/details/70 ...

  9. css dropdown menu

    <ul> <li class="left">abc</li> <li class="middle" id=" ...

  10. 【commons】字符串工具类——commons-lang3之StringUtils

    类似工具见Hutool-StrUtil 一.起步 引入maven依赖 <!-- https://mvnrepository.com/artifact/org.apache.commons/com ...