bson文件的切分
描述
最近遇到问题需要将较大的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文件的切分的更多相关文章
- 通过 bsondump 命令工具 解析备份产生的bson文件
bsondump命令是将BSON格式的文件转换为可读性更强的文件格式,例如转为为JSON 格式的文档,bsondump默认转换为json格式的文档. 当通过mongodump命令进行备份时,如果有参数 ...
- Python将mongodb导出的bson文件转为字典对象
Python将mongodb导出的bson文件转为字典对象 安装bson包, sudo pip install bson 示例 # 解决编码问题 import sys reload(sys) sys. ...
- MongoDB导入bson文件(元数据),mongorestore命令行方式导入
MongoDB导入bson文件(元数据),mongorestore命令行方式导入 不推荐使用MongoDB Compass等图形化数据库管理软件,例如MongoDB Compass只能导入json和c ...
- MongoDB从bson文件中恢复数据
首先需要到mangodb的安装目录的bin下面找到mongorestore.exe WIN10系统MongoDB安装目录bin文件夹下没有mongorestore.exe 先下载工具 https:/ ...
- 如何将mongodb bson文件转成json文件
使用mongodb自带的命令 bsondump collection.bson > collection.json
- MongoDB导入文件夹(内含json和bson文件)
1. 使用mongo命令将数据库删除: mongo命令: use db_name; db.dropDatabase() 2. 导入(指定文件夹)数据: linux命令: mongorestore -d ...
- hadoop拾遗(一)---- 避免切分map文件
有些程序可能不希望文件被切分,而是用一个mapper完整处理每一个输入文件.例如,检查一个文件中所有记录是否有序,一个简单的方法是顺序扫描第一条记录并并比较后一条记录是否比前一条要小.如果将它实现为一 ...
- sql脚本长度限制及linux下文件切分
无意翻出以前笔记,切分sql文件,每10万条加一个commit.半天都想不起来应用的场景,能想起来的再加上查的资料记录一下. 在Oracle数据库中,频繁的commit会引起大量Redo Log的物理 ...
- [Linux] 随机切分文件内容
1.从原文件中随机选出若干行 可以直接用shuf命令就可以完成: $ shuf -n source.txt > target.txt shuf命令的说明: $ shuf --help Usage ...
随机推荐
- (CodeForces - 5C)Longest Regular Bracket Sequence(dp+栈)(最长连续括号模板)
(CodeForces - 5C)Longest Regular Bracket Sequence time limit per test:2 seconds memory limit per tes ...
- ffmpeg 从mp4上提取H264的nalu
转自http://blog.csdn.net/gavinr/article/details/7183499 1.获取数据 ffmpeg读取mp4中的H264数据,并不能直接得到NALU,文件中也没有储 ...
- 安装oracle11g时遇到环境不满足最低要求
在安装oracle11g时出现问题:INS-13001环境不满足最低要求 解决方法:找到下载解压后的文件,依次打开以下文件路径:Oracle11g\database\stage\cvu, 在cvu文件 ...
- Linux -- 用户组篇
Linux -- 用户与用户组 1.Linux 系统中有三种角色:所有者(用户),用户组与其他人,一张图可以说明用户与用户组的关系. 如图,某公司相当于一个用户组,该用户组下有A,B两个用户,用户拥有 ...
- 2018 CVTE 前端校招笔试题整理
昨天晚上(7.20)做了CVTE的前端笔试,总共三十道题,28道多选题,2道编程题 .做完了之后觉得自己基础还是不够扎实,故在此整理出答案,让自己能从中得到收获,同时给日后的同学一些参考. 首先说一下 ...
- #leetcode刷题之路13-罗马数字转整数
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M.字符 数值I 1V 5X 10L 50C 100D 500M 1000例如, 罗马数字 2 写做 II ,即为两个并列的 1.12 写 ...
- python打印99乘法表
代码如下: print(XXX,end="\t") #表示打印不换行 附带python部分转义字符:
- Vmware文件类型
### vmx ###> 虚拟机启动的配置文件+ 包含`.encoding`.`displayName`.`memsize`等基本配置信息,还包括一些链接文件的位置如`nvram`(非易变RAM ...
- 了解jQuery并掌握jQuery对象和DOM对象的区别
jQuery的优势: 开源--开放源代码 轻量级 强大的选择器 出色的DOM操作(对DOM元素的一个增删改查) 完善的Ajax,出色的浏览器兼容性,丰富的插件支持,完善的文档(说明书) 链式操作方式, ...
- AJAX 动态加载后台数据 绑定select
<select id="select"> <!--下拉框数据动态加载--> </select> js:(使用jquery) $(document ...