最近有一个需求,就是之前mongodb库导出的Json文件,需要把Json文件里面的数据读取出来,入到SqlServer库中;MongoDB导出的文件时这个样子的;
{
"_id" : ObjectId("53f16f3b8c9bf1b358000118"),
"__v" : NumberInt(0),
"name": "张三",
"age" : 20
}
{
"_id" : ObjectId("53f16f3b8c9bf1b358000128"),
"__v" : NumberInt(0),
"name": "李四",
"age" : 22
}
{
"_id" : ObjectId("53f16f3b8c9bf1b358000138"),
"__v" : NumberInt(0),
"name": "王五",
"age" : 23
}
{
"_id" : ObjectId("53f16f3b8c9bf1b358000148"),
"__v" : NumberInt(0),
"name": "马六",
"age" : 24
}
经常操作JSON格式数据的都知道。这并不是一个严格的JOSN数据集合。因为,在JOSN集合中,最外层是被"[ ]" 包裹起来的;而每一个对象之间,在 "}" 的后面以 " ,"相隔;这种JSON文件在用com.alibaba.fastjson读取的时候,只能读取第一个对象;剩下的对象则不会读取;而且在直接读取时,由于 “Object_Id” 以及 “NumberInt(0)” 这种是从MongoDB中导出自带的一些数据。需要把它们处理一下;如 “ObjectId("53f16f3b8c9bf1b358000118")” 最后处理成 “53f16f3b8c9bf1b358000118”;“NumberInt(0)” 处理成 “0”;这样解析时,便不会出现解析不了的情况;
如果你的JOSN是一个大文件,手动添加 " [ " " ] " 和 " ," 肯定是一个很蠢的方式;那么应该用程序读,再用程序写一份可以被fastjson解析的json文件;
做法是,传入json文件所在的路径,在另一处生成可以被fastjson解析的json文件;代码如下
/**
* 通过输入的路径originPath,读取originPath下的所有json文件;
* 在格式化之后,在另一个路径orderPath下生成同名的json文件名称;
* @param originPath 原json文件路径
* eg:C:\\Users\\Administrator\\Desktop\\readJson\\User.json
* @param orderPath 格式完成的json路径
*eg:C:\\Users\\Administrator\\Desktop\\readJson\\right\\User.json
*/
public static void genetateJsonFormatFile(String originPath,String orderPath){
File file = new File(originPath);
BufferedReader br = null;
BufferedWriter out = null;
try {
long position = 1;
File fileCreate = new File(orderPath);
if(!fileCreate.exists()){
fileCreate.createNewFile();
}
out = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(fileCreate,true),"utf-8"));
out.write("[" + "\r\n");
InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "utf-8");
br = new BufferedReader(isr);
String line = null;
while((line = br.readLine())!=null){
// 过滤第一个{,剩下的按照要求在{下追加“,”
if((position == 0 && line.indexOf("{") > -1)){
out.write(",");
//position = 0;
}else if((position !=0 && line.indexOf("{") > -1)){
position = 0;
}
System.out.println(line);
String filterLine = null;
if(line.indexOf("ObjectId(") > 0){
filterLine = line.replace("ObjectId(", "");
if(filterLine.indexOf(")") > 0){
filterLine = filterLine.replace(")", "");
}
}
if(line.indexOf("NumberInt(") > 0){
filterLine = line.replace("NumberInt(", "");
if(filterLine.indexOf(")") > 0){
filterLine = filterLine.replace(")", "");
}
}
if(null != filterLine){
out.write(filterLine + "\r\n");
}else{
out.write(line + "\r\n");
}
}
out.write("]" + "\r\n");
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(br!=null){
br.close();
}
if(out != null){
out.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
这个时候,程序格式化之后的文件就是这个样子的;
[
{
"_id" : "53f16f3b8c9bf1b358000118",
"__v" : 0,
"name": "张三",
"age" : 20
},
{
"_id" : "53f16f3b8c9bf1b358000128",
"__v" : 0,
"name": "李四",
"age" : 22
},
{
"_id" : "53f16f3b8c9bf1b358000138",
"__v" : 0,
"name": "王五",
"age" : 23
},
{
"_id" : "53f16f3b8c9bf1b358000148",
"__v" : 0,
"name": "马六",
"age" : 24
}
]
原JOSN文件已经被解析成fastjson可以直接解析的json数据格式;但是一个json文件有60MB大小;肯定不能像下面一样读取(读取大文件时,一个很SB的写法)
/**
* 通过路径读取json文件
* FileUtils 是 commons.io 包下的方法
*/
@Test
public void contextLoadsByPath() {
ClassPathResource resource = new
ClassPathResource("E:\\luqianzhen\\Jsons\\Student.json");
File file = null;
try {
file = resource.getFile();
String jsonString = FileUtils.readFileToString(file);
JSONObject jsonObject = JSONObject.parseObject(jsonString);
System.out.println(jsonObject);
} catch (IOException e) {
e.printStackTrace();
}
}
原因是,60MB的文件,用这种方式读取出来,放在一个String类型的jsonString变量当中,而变量是放在内存中的。相当于把60MB多大小的内容,放在了内存里面,这种方式可能会导致虚拟机内存溢出;及其不推荐;
应该用下面这种方法,通过fastjson的JSONReader对象读取大文件;
/**
* 通过传入的class类型,返回装配好的class类对象的集合
* @param jsonName 方法中没有用到此参数
* @param jsonPath eg:C:\\Users\\Administrator\\Desktop\\readJson\\a\\User.json
* @param type 已经建好的实体类对象.class
* @param
* @return
*/
public static List getOrderObjectsByClass(String jsonName ,String jsonPath, Class type){
LinkedList returnList = new LinkedList();
File file = new File(jsonPath);
InputStreamReader isr = null;
BufferedReader bufferedReader = null;
try {
isr = new InputStreamReader(new FileInputStream(file), "utf-8");
bufferedReader = new BufferedReader(isr);
JSONReader reader = new JSONReader(bufferedReader);
reader.startArray();
while (reader.hasNext()) {
T readObject = reader.readObject(type);
returnList.add(readObject);
}
reader.endArray();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
try {
if(null != isr){
isr.close();
}
if(null != bufferedReader){
bufferedReader.close();
}
} catch (Exception e2) {
}
}
return returnList;
}
既然已经拿到了集合对象,下一步你一定知道怎么操作;
文章有什么缺陷,欢迎留言,一起讨论,一起进步;