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

      最近有一个需求,就是之前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;
    }

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

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

你可能感兴趣的:(Java)