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