基于流式输入输出 使用Java借助GSON库 实现对大型asc文件的读入解析 并输出为JSON文件

致谢

DOSKEY_jason

参考文章

奇伢 - 使用流的方式读写JSON(GSON)

1 为什么要使用流式输入输出(使用情景)

解决 在进行非流式输入输出时,当需处理的文件 过大 时(比如上G的数据文件),无法将整个完整的文件放入内存,导致堆栈溢出,GC溢出等情况。

2 目标、主要思路及相关方法

2.1 目标

将大型asc文件的数据解析后,转换成JSON文件

2.2 思路

对读入的asc文件每次提取一部分内容,解析后,调用GSON库生成相应的一部分JSON文件并写出。

2.3 相关方法

2.3.1 读入相关

使用的主要java相关读入类

  • BufferedReader

其相关方法

  • bufferedReader.readLine() - - 按行读取
2.3.2 输出相关

使用的主要GSON类

  • JsonWriter

其相关方法

  • new JsonWriter(new FileWriter(xxx)) - - 构造方法
  • writer.beginObject() - - 开始写JSON文件 相当于写JSON文件的 { 对象开始符号
  • writer.endObject() - - 结束JSON文件 相当于写JSON文件的 } 对象结束符号
  • writer.name(xxx) - - 写入一个键名为xxx的键
  • writer.value(yyy) - - 写入一个值为yyy的值
  • writer.name(xxx).value(yyy) - - 写入一个键为xxx,值为yyy的键值对
  • writer.beginArray() - - 开始一个数组 相当于写JSON文件的 [ 符号
  • writer.endArray() - - 结束一个数组 相当于写JSON文件的 ] 符号
  • writer.close() 关闭输出器

相关方法输出解析示例
在这里插入图片描述

3 示例

3.1 环境

GSON库的maven依赖

		<!--GSON依赖-->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.6</version>
        </dependency>

3.2 测试数据

读入的asc文件
在这里插入图片描述
文件的类似基本结构(按行排列,不定量的空格做单个数据分隔)
读入的asc文件的结构 关系到 其相应 提取数据的策略
在这里插入图片描述

3.3 测试代码 - Java

main()入口方法

//        输入设置
        String fileName = "zhemindem_30.asc";
        String filePath = "C:\\dataTest\\asc\\";
        String bigFile = filePath + fileName;

//        输出设置
        String outFileParent2 = "E:\\json\\";
        String outputFile2 = outFileParent2 + fileName.replaceAll(".asc", ".json");
        String encoding2 = "utf-8";

//        转换方法
        convertBigFile(bigFile, outputFile2, encoding2);

具体转换方法 - convertBigFile()

    public static void convertBigFile(String inputFile, String outputFile, String encoding){
//        将文件名作为主体数据部分的键名
        String dataKey = inputFile.substring(inputFile.lastIndexOf("\\")+1).split(".asc")[0];

        File file = new File(inputFile);
        FileReader fileReader = null;
        BufferedReader bufferedReader = null;
        JsonWriter writer;

        String temp;
        int count = 0;
//        asc文件总行数
        int nrows = 0;
//        asc文件总列数
        int ncols = 0;

        try {
            fileReader = new FileReader(file);
//            读入器
            bufferedReader = new BufferedReader(fileReader);
//            写出器
            writer = new JsonWriter(new FileWriter(outputFile));
            //开始准备生成JSON文件
            writer.beginObject(); // {

            while((temp = bufferedReader.readLine())!=null){
                System.err.println("currentRow: " + count);
//                解析当前行,前6行 为属性,后面行 为数据
                String[] result = temp.split(" +");
                if (count == 0 ) {
                    System.out.println(count + " : " + temp);
//                    result[0]属性名,result[1]属性值
                    ncols = Integer.parseInt(result[1]);
                    writer.name(result[0]).value(ncols);
                }else if(count == 1){
                    System.out.println(count + " : " + temp);
                    nrows = Integer.parseInt(result[1]);
                    writer.name(result[0]).value(nrows);
                }else if(count < 5){
                    System.out.println(count + " : " + temp);
                    writer.name(result[0]).value(Double.parseDouble(result[1]));
                }else if(count == 5){
                    System.out.println(count + " : " + temp);
                    writer.name(result[0]).value(Integer.parseInt(result[1]));
                    //开始准备写入数据
                    writer.name(dataKey);
                    writer.beginArray(); // [
                }else if(count < nrows){
                    writer.beginArray(); // [
                    for(String eachCol: result){
                        writer.value(Short.parseShort(eachCol));
                    }
                    writer.endArray(); // ]
                }else if(count == nrows){
                    writer.endArray(); // ]
                    //结束JSON文件
                    writer.endObject(); // }
                    writer.close();
                    System.out.println("写出器退出!");
                }
                else{
                    break;
                }
                count++;
            }
            fileReader.close();
            bufferedReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try{
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
                if(fileReader != null){
                    fileReader.close();
                }
                System.out.println("读取文件成功!");
            }catch (IOException e) {
                System.out.println("读取文件失败!");
                e.printStackTrace();
            }
        }
    }

3.4 测试结果

在这里插入图片描述

3.5 注意事项

① 对自定义的读入文件的按行读取,读取解析时需要根据读入文件的特点进行设计。(示例为zhemindem_30.asc文件)

② 需要小心、准确使用如下方法
writer.beginArray();
writer.endArray();
若出现不恰当的使用,导致多出 [ 符号或者 ] 符号,将出现 nest 异常,使程序退出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值