fastJson读取Json大文件&数据入库

    xiaoxiao2025-03-01  35

          最近有一个需求,就是之前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 <T> * @return */ public static <T> List<T> getOrderObjectsByClass(String jsonName ,String jsonPath, Class<T> type){ LinkedList<T> returnList = new LinkedList<T>(); 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; }

             既然已经拿到了集合对象,下一步你一定知道怎么操作;

             文章有什么缺陷,欢迎留言,一起讨论,一起进步;

    最新回复(0)