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

Posted 新来的大狮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于流式输入输出 使用Java借助GSON库 实现对大型asc文件的读入解析 并输出为JSON文件相关的知识,希望对你有一定的参考价值。

基于流式输入输出 使用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 异常,使程序退出。

以上是关于基于流式输入输出 使用Java借助GSON库 实现对大型asc文件的读入解析 并输出为JSON文件的主要内容,如果未能解决你的问题,请参考以下文章

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

你真的会用Gson吗?Gson使用指南

Gson通过借助TypeToken类来解决这个问题

Android:Gson通过借助TypeToken获取泛型参数的类型的方法

使用 GSON 的 JsonReader 流式传输 Json 文件时,您可以将对象转储为字符串吗?

Android Studio 中的 Gson 库