java读取GPS观测文件(IO流、ArrayList集合、HashMap集合练习)

package cn.luoxue.reader_o_file;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Read_O_file {
    /**
     * 读取GPS观测文件O文件
     * @param args
     */
    public static void main(String[] args) {
        //用同一个FileReader 的对象fr作为参数创建的第二个BufferedReader对象读的数据为空,这里创建两个,fr1计算历元个数的时候用
        FileReader fr = null;
        FileReader fr1 = null;
        BufferedReader br = null;
        BufferedReader br1 = null;
        try {
            //创建FileReader对象
            fr = new FileReader("Test.O");
            fr1 = new FileReader("Test.O");
            //创建BufferReader对象
            br = new BufferedReader(fr);
            br1 = new BufferedReader(fr1);
            //通过readLine()方法一行一行的度数据
            String line = "";
            while(((line = br.readLine()) != null)){
                
                //读取头文件内的内容
                //substring(0, 20);前包括后不包括,实际所取的是 索引 0 ~ 19 的内容
                switch(line.substring(60).trim()){
                //判断该行是否以RINEX VERSION / TYPE结尾
                case "RINEX VERSION / TYPE":
                    String  rinexVersion = line.substring(0, 20).trim();
                    String fileType = line.substring(20, 40).trim();
                    String dataType = line.substring(40, 60).trim();
                    System.out.println("版本号为:" + rinexVersion + " 文件类型为: " + fileType + " 数据类型为:" + dataType);
                    continue;
                //判断该行是否以COMMENT结尾
                /*case "COMMENT":
                    String comment = line.substring(0,60).trim();
                    System.out.println("注释内容为:" + comment);
                    continue;*/
                case "PGM / RUN BY / DATE":
                    //建本数据文件所采用程序的名称
                    String program_Name = line.substring(0, 20).trim();
                    //创建本数据文件单位的名称
                    String organization_Name = line.substring(20, 40).trim();
                    //创建文件的时间
                    String date_Time = line.substring(40, 60).trim();
                    //输出
                    System.out.println("程序的名称为:" + program_Name + " 单位名称为:" + organization_Name + " 创建文件的时间为:" + date_Time);
                    continue;
                case "MARKER NAME":
                    //标记点名
                    String marker_Name = line.substring(0, 60).trim();
                    //输出
                    System.out.println("标记点名为:" + marker_Name);
                    continue;
                case "MARKER NUMBER":
                    //标记点名
                    String marker_Number = line.substring(0, 60).trim();
                    //输出
                    System.out.println("标记点数量为:" + marker_Number);
                    continue;
                case "OBSERVER / AGENCY":
                    //观测者的名称
                    String observer_Name = line.substring(0, 20).trim();
                    //观测者所在机构
                    String observer_Organization = line.substring(20, 40).trim();
                    //打印
                    System.out.println("观测者的名称为:" + observer_Name + " 观测者所在机构:" + observer_Organization);
                    continue;
                case "REC # / TYPE / VERS":
                    //接收机的数量
                    String rec_Number = line.substring(0, 20).trim();
                    //接收机的型号
                    String rec_Type = line.substring(20, 40).trim();
                    //版本
                    String rec_Versions = line.substring(40, 60).trim();
                    System.out.println("接收机的数量为: " +  rec_Number + " 接收机的型号为:" + rec_Type + " 接收机的版本" + rec_Versions);
                    continue;
                case "ANT # / TYPE":
                    String ant_Number = line.substring(0, 19).trim();
                    String ant_Type = line.substring(20, 40).trim();
                    System.out.println("天线的数量: " + ant_Number + " 天线的型号: " + ant_Type);
                    continue;
                case "APPROX POSITION XYZ":
                    String x = line.substring(0, 14).trim();
                    String y = line.substring(14, 28).trim();
                    String z = line.substring(28, 42).trim();
                    System.out.println("x = " + x + " y = " + y + " z = " + z );
                    continue;
                    
                case "ANTENNA: DELTA H/E/N": // 天线高度、天线中心相对标记点东向和北向距离
                    String H = line.substring(0, 14).trim();
                    String E = line.substring(14, 28).trim();
                    String N = line.substring(28, 42).trim();
                    System.out.println("H = " + H + " E = " + E + " N = " + N );
                    continue;
                case "TIME OF FIRST OBS": //首次观测时间
                    String first_Year = line.substring(0, 6).trim();
                    String first_Month = line.substring(6, 12).trim();
                    String first_Day = line.substring(12, 18).trim();
                    String first_Hour = line.substring(18, 24).trim();
                    String first_Minute = line.substring(24, 30).trim();
                    String first_Second = line.substring(30, 43).trim();
                    String time_System = line.substring(43, 51).trim();
                    System.out.println("首次观测时间:" + first_Year + "" 
                            + first_Month + ""
                            + first_Day + ""
                            + first_Hour + ""
                            + first_Minute + ""
                            + first_Second + "");
                    System.out.println("时间系统为:" + time_System);
                    continue;
                case "TIME OF LAST OBS"://最后观测时间
                    String last_Year = line.substring(0, 6).trim();
                    String last_Month = line.substring(6, 12).trim();
                    String last_Day = line.substring(12, 18).trim();
                    String last_Hour = line.substring(18, 24).trim();
                    String last_Minute = line.substring(24, 30).trim();
                    String last_Second = line.substring(30, 43).trim();
                    String last_System = line.substring(43, 51).trim();
                    System.out.println("最后观测时间:" + last_Year + "" 
                            + last_Month + ""
                            + last_Day + ""
                            + last_Hour + ""
                            + last_Minute + ""
                            + last_Second + "");
                    System.out.println("时间系统为:" + last_System);
                    continue;
                case "INTERVAL": //以秒为单位的时间间隔
                    String inteval = line.substring(0, 6).trim();
                    System.out.println("以秒为单位的时间间隔:" + inteval);
                    continue;
                case "LEAP SECONDS"://跳秒
                    String leap_Seconds = line.substring(0, 6).trim();
                    System.out.println("跳秒数为:" + leap_Seconds);
                    continue;
                case "# / TYPES OF OBSERV"://观测类型数量及观测类型
                    List<String> observe_Type = new ArrayList<String>();
                    String type_Number = line.substring(0, 6).trim();
                    int int_Type_Number = Integer.valueOf(type_Number).intValue();
                    //这里仅仅考虑了观测值在九个以内的情况(即观测值类型仅仅在一行时候的情况!)
                    for (int i = 0; i < int_Type_Number; i++) {
                        switch(line.substring((i+1)*6, (i+2)*6).trim()){
                        case "p1":
                            observe_Type.add("p1");
                        continue;
                        case "p2":
                            observe_Type.add("p2");
                        continue;
                        case "C1":
                            observe_Type.add("C1");
                        continue;
                        case "C2":
                            observe_Type.add("C2");
                        continue;
                        case "L1":
                            observe_Type.add("L1");
                        continue;
                        case "L2":
                            observe_Type.add("L2");
                        continue;
                        case "S1":
                            observe_Type.add("S1");
                        continue;
                        case "S2":
                            observe_Type.add("S2");
                        continue;
                        default:
                        break;
                        }
                        break;
                    }
                    System.out.println("observe_Type" + observe_Type);
                    continue;
                case "END OF HEADER":
                    break;
                default:
                    continue;
                }
                break;
            }
            //计算历元数
            int epochNum=0;
            String line1 = "";
            while((line1 = br1.readLine()) != null){
                if(line1.trim().endsWith("END OF HEADER")){
                    break;
                }
            }
            System.out.println(line1);
            while((line1 = br1.readLine()) != null){
                if(line1.contains("G")){
                    epochNum++;
                }
            }
            System.out.println("历元数为:" + epochNum);
            //通过两种方式存储每个历元的观测数据
            //第一种方式:以历元作为主键的HashMap集合
            Map<Integer, Map<String, List<Double>>> epoch_Observe_Map = new HashMap<Integer, Map<String, List<Double>>>();
            //第二种方式:ArrayList集合
            List<Map<String, List<Double>>> epoch_Observe_List = new ArrayList<Map<String, List<Double>>>();
            //遍历所有历元
            for (int i = 0; i < epochNum; i++) {
                //以卫星ID作为主键的HashMap集合,存储每个卫星的观测数据
                //(HashMap集合的key键:无序、唯一的;value值:无序、不唯一)
                //集合中存储数据的顺序为乱序的,不过不影响可以通过key键值(即卫星ID)来查数据
                Map<String, List<Double>> satelite_Observe_Map = new HashMap<String, List<Double>>();
                line = br.readLine();
                // 卫星个数
                int satelite_Num = Integer.valueOf(line.substring(29, 32).trim()).intValue();
                //存储卫星的ID
                //这里每次循环都重新new了一下,起到了清空集合的作用(效率太低)
                List<String> satelite_Id_List = new ArrayList<String>();  
                //提取卫星ID
                for (int j = 0; j < satelite_Num; j++) {
                    satelite_Id_List.add(line.substring(32 + j * 3, 35 + j * 3).trim());
                }
                //(这里可以做一个判断,如果观测数据类型的个数大于5个和小于等于5个的情况各用一种方式提取)
                //此处仅仅考虑了大于5的情况
                for (int j = 0; j < satelite_Num; j++) { //每次循环读两行 ① ②
                    //存储每颗卫星的观测数据
                    //同样的,每次循环都重新new了一下,起到了清空集合的作用(但是效率太低)
                    List<Double> observe_Date_List = new ArrayList<Double>();
                    line = br.readLine();  //
                    for (int j2 = 0; j2 < 5; j2++) {
                        observe_Date_List.add(Double.valueOf(line. substring(j2 * 16, 16 + j2 * 16).trim()).doubleValue());
                    }    
                    line = br.readLine();  //
                    observe_Date_List.add(Double.valueOf(line. substring(0, 16).trim()).doubleValue());
                    //读完一个卫星的数据
                    satelite_Observe_Map.put(satelite_Id_List.get(j), observe_Date_List);
            //数组能够存储基本数据类型、引用型数据类型; 而集合只能存储引用型数据类型
//清空集合 这样清空集合会出现问题 ,貌似因为observe_Date_List和satelite_Observe_Map中添加的observe_Date_List指向的是同一块儿内存 //((会把连带着把satelite_Observe_Map中添加的observe_Date_List集合也给清空了)) //observe_Date_List.clear(); } /*调试测试 * System.out.println("satelite_Observe_Map.keySet()为:" + satelite_Observe_Map.keySet()); Set<String> set = satelite_Observe_Map.keySet(); Iterator<String> it = set.iterator(); while(it.hasNext()){ String key = it.next(); Iterator<Double> its = satelite_Observe_Map.get(key).iterator(); while(its.hasNext()){ double straa = its.next(); System.out.print(" " + straa); } }*/ //两种存储方式的集合分别添加每个历元的观测数据 epoch_Observe_Map.put(i, satelite_Observe_Map); epoch_Observe_List.add(satelite_Observe_Map); } //测试,输出第1个历元卫星号为G01的观测数据 System.out.println("存历元数据的HashMap集合的第一个历元卫星号为G01的观测数据" + epoch_Observe_Map.get(0).get("G01")); System.out.println("存历元数据的ArrayList集合的第一个历元卫星号为G01的观测数据" + epoch_Observe_List.get(0).get("G01")); } catch (FileNotFoundException e) { System.err.println("文件不存在!"); e.printStackTrace(); } catch (IOException e){ e.printStackTrace(); }finally{ try { if(br != null){ br.close(); } if(fr != null){ fr.close(); } } catch (IOException e) { e.printStackTrace(); } } } }

O文件下载:https://files.cnblogs.com/files/ludengxiadeyingzi/O%E6%96%87%E4%BB%B6.zip

原文地址:https://www.cnblogs.com/ludengxiadeyingzi/p/7430286.html