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 ...
随机推荐
- c++中如 <类名 类名::对象> 是什么意思
CComplex CComplex::add(CComplex &x) (这一句 不懂为何 类名 类名::对象) { CComplex y(real+x.real,image+x.image) ...
- STM32之定时器输入捕获
1.输入捕获模式可以用来测量脉冲宽度或者测量频率.STM32的定时器,除了TIM6和TIM7,其他定时器都有输入捕获功能.STM32的输入捕获,简单的说就是通过检测TIMx_CHx上的边沿信号,在边沿 ...
- GoBelieve-国内唯一开源IM服务
GoBelieve-国内唯一开源IM服务 1. 一小时接入 专注IM,无冗余功能 几行代码,一小时接入 省时省力. 2. 自由定制 提供最新源码, 自行二次开发,业务协议 交互视觉均可根据业务需求 自 ...
- Appstore|IPA
ios提审报错:No suitable application records were found. Verify your bundle identifier 'xx' is correct - ...
- 利用binlog2sql闪回丢失数据
today,i'll using the open source tool named "binlog2sql" which is release by danfengch ...
- keepalived+nginx+tomcat+redis实现负载均衡和session共享(原创)
keepalived+nginx+tomcat+redis实现负载均衡和session共享 直接上链接,码了一天,就不再重写了,希望能帮到大家,有问题欢迎留言交流.
- Tornado 线程池应用
Tornado是一个异步框架,在异步操作的时候能提升程序的处理性能.但是如果在程序中碰到同步的逻辑,由于GIL的关系,会直接卡死,导致性能急剧下降. 目前对于mongodb以及redis都有比较不错的 ...
- Java敲地鼠代码
package test; import java.awt.EventQueue; import java.awt.event.MouseAdapter; import java.awt.event. ...
- Java : java基础(5) Socket网络编程
使用 DatagramSocket 创建一个 UDP协议的Socket, 用DatagramPacket创建一个数据包,可以指定ip和端口号以及包的数据,用socket.send()可以发送这个数据包 ...
- [转]MySQL常用字符串函数
本文转载自:http://www.cnblogs.com/geaozhang/ 是最常用的的一种函数,在一个具体应用中通常会综合几个甚至几类函数来实现相应的应用: 1.LOWER(column|str ...