android如何解析C++传递过来的.dat数据

        以前写Android程序解析的数据大多是xml和json数据,但最近因为项目需要以及老师的强制要求,开始解析C++发送过来.dat的数据。网上搜索了很久也没有相关的api可供使用,所以我采用的是根据.dat的数据所占用多少字节进行解码的方法。

       c++的结构体:

  

  struct _tagFileHeader
  {
  #define POINT_NUM 90
  #define FILE_NAME_LEN 260

  unsigned short usFileHeaderLen; //文件头长度

  char arrFileName[FILE_NAME_LEN]; //完整的数据文件名
  unsigned short usWidth; //图像(矩阵)宽度
  unsigned short usHeight; //图像(矩阵)高度
  unsigned short usBPP; //每个像素所占的字节数

  unsigned short usFitType; //拟合类型,0:双指数,1:二阶多项式,2:三阶多项式
  int nGain;      //相机增益
  int nExposureTime;   //相机曝光时间
  float fC0; //拟合系数,下同
  float fC1;
  float fC2;
  float fC3;
  float fC4;
  float fC5;
  float fC6;
  unsigned short usTempOffset; //温度偏移量

  unsigned short usMaxHighTemp[LINE_NUM]; //最高温度
  unsigned short usMinLowTemp[LINE_NUM]; //最低温度
  unsigned short usMeanTemp[LINE_NUM]; //平均温度

  unsigned short usLineNum; //= 3; //划线数目(另外两条保留)
  unsigned short usPointNum; //= 10; //每条线上虚拟热电偶数目
  };
 
  我通过ftp协议将包含上面结构体信息的.dat数据下载到本地进行解析,下面是我的解析代码:


import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import com.ht.masteel.domain.DatDomain;

import android.content.Context;
import android.widget.Toast;

/***
 * .dat文件的解析类,用于解析从服务器段下载下来的.dat文件
 *
 * @author htao
 *
 */
public class DatParserUtils {

// 定义一个集合,用来保存JavaBean对象
        List<DatDomain> datLists = new ArrayList<DatDomain>();

        DatDomain datDomain = new DatDomain();
        // 读取.dat文件,并将之保存到集合中
        ArrayList<Byte> byteLists = (ArrayList<Byte>) readDatFiles(path,
                fileName, context);
        
        if(byteLists!=null){
            // if(byteLists!=null&&byteLists.size()!=0){
            // 获取文件头长度 unsigned short usFileHeaderLen

            try {
                // 获取文件头的长度
                usFileHeaderLen = AsciiToUnsignedShort(byteLists.get(0),
                        byteLists.get(1));

                // 将文件头保存到javabean对象中
                datDomain.setUsFileHeaderLen(usFileHeaderLen);// 将文件头的长度添加到JavaBean对象

                // 获取完整的数据文件名 char arrFileName[FILE_NAME_LEN]
                String arrFileName = "";
                for (int i = 2; i < 262; i++) {

                    arrFileName += byteToAscii(byteToBinary(byteLists.get(i)));
                    arrFileName = arrFileName.trim();// 去掉数据文件名数组多余的空格

                }
                datDomain.setArrFileName(arrFileName);// 将数据文件名添加到JavaBean中

                // 获取图像矩阵的宽度 unsigned short usWidth

                usWidth = AsciiToUnsignedShort(byteLists.get(262),
                        byteLists.get(263));

                datDomain.setUsWidth(usWidth);

                // 获取图像矩阵的高度 unsigned short usHeight

                usHeight = AsciiToUnsignedShort(byteLists.get(264),
                        byteLists.get(265));

                datDomain.setUsHeight(usHeight);// 将图像矩阵的高度添加到JavaBean中

                // usBPP获取每个像素所占的字节数 unsigned short usBPP

                usBPP = AsciiToUnsignedShort(byteLists.get(266), byteLists.get(267));

                datDomain.setUsBPP(usBPP);

                // 相机增益 int nGain

                nGain = asciiToInteger(byteLists.get(272), byteLists.get(273),
                        byteLists.get(274), byteLists.get(275));

                datDomain.setnGain(nGain);
                // nExposureTime 相机曝光时间 int nExposureTime

                nExposureTime = asciiToInteger(byteLists.get(276),
                        byteLists.get(277), byteLists.get(278), byteLists.get(279));

                datDomain.setnExposureTime(nExposureTime);

                // 拟合系数fC0,fC1,fC2,fC3,fC4,fC5,fC6 (float)

                fC0 = asciiToFloat(byteLists.get(280), byteLists.get(281),
                        byteLists.get(282), byteLists.get(283));

                datDomain.setfC0(fC0);

                fC1 = asciiToFloat(byteLists.get(284), byteLists.get(285),
                        byteLists.get(286), byteLists.get(287));

                datDomain.setfC1(fC1);

                fC2 = asciiToFloat(byteLists.get(288), byteLists.get(289),
                        byteLists.get(290), byteLists.get(291));

                datDomain.setfC2(fC2);

                fC3 = asciiToFloat(byteLists.get(292), byteLists.get(293),
                        byteLists.get(294), byteLists.get(295));

                datDomain.setfC3(fC3);

                fC4 = asciiToFloat(byteLists.get(296), byteLists.get(297),
                        byteLists.get(298), byteLists.get(299));

                datDomain.setfC4(fC4);

                fC5 = asciiToFloat(byteLists.get(300), byteLists.get(301),
                        byteLists.get(302), byteLists.get(303));

                datDomain.setfC5(fC5);

                fC6 = asciiToFloat(byteLists.get(304), byteLists.get(305),
                        byteLists.get(306), byteLists.get(307));

                datDomain.setfC6(fC6);

                // 温度偏移量 unsigned short usTempOffset;

                usTempOffset = AsciiToUnsignedShort(byteLists.get(308),
                        byteLists.get(309));

                datDomain.setUsTempOffset(usTempOffset);

                // 最高温度 unsigned short usMaxHighTemp[LINE_NUM]=unsigned short
                // usMaxHighTemp[3]

                usMaxHighTemp1 = AsciiToUnsignedShort(byteLists.get(310),
                        byteLists.get(311));
                usMaxHighTemp2 = AsciiToUnsignedShort(byteLists.get(312),
                        byteLists.get(313));
                usMaxHighTemp3 = AsciiToUnsignedShort(byteLists.get(314),
                        byteLists.get(315));

                datDomain.setUsMaxHighTemp1(usMaxHighTemp1);
                datDomain.setUsMaxHighTemp2(usMaxHighTemp2);
                datDomain.setUsMaxHighTemp3(usMaxHighTemp3);

                // 最低温度unsigned short usMinLowTemp[LINE_NUM]=unsigned short
                // usMinLowTemp[3]

                usMinLowTemp1 = AsciiToUnsignedShort(byteLists.get(316),
                        byteLists.get(317));
                usMinLowTemp2 = AsciiToUnsignedShort(byteLists.get(318),
                        byteLists.get(319));
                usMinLowTemp3 = AsciiToUnsignedShort(byteLists.get(320),
                        byteLists.get(321));

                datDomain.setUsMinLowTemp1(usMinLowTemp1);
                datDomain.setUsMinLowTemp2(usMinLowTemp2);
                datDomain.setUsMinLowTemp3(usMinLowTemp3);

                // 平均温度 unsigned short usMeanTemp[LINE_NUM]=unsigned short
                // usMeanTemp[3]

                usMeanTemp1 = AsciiToUnsignedShort(byteLists.get(322),
                        byteLists.get(323));
                usMeanTemp2 = AsciiToUnsignedShort(byteLists.get(324),
                        byteLists.get(325));
                usMeanTemp3 = AsciiToUnsignedShort(byteLists.get(326),
                        byteLists.get(327));

                datDomain.setUsMeanTemp1(usMeanTemp1);
                datDomain.setUsMeanTemp2(usMeanTemp2);
                datDomain.setUsMeanTemp3(usMeanTemp3);

                // 划线数目(另外两条保留)unsigned short usLineNum; //= 3;

                usLineNum = AsciiToUnsignedShort(byteLists.get(328),
                        byteLists.get(329));

                datDomain.setUsLineNum(usLineNum);

                // 每条线上虚拟热电偶数目 unsigned short usPointNum; //= 10

                usPointNum = AsciiToUnsignedShort(byteLists.get(330),
                        byteLists.get(331));

                datDomain.setUsPointNum(usPointNum);

                bLineExist1 = asciiToBool(byteLists.get(332), byteLists.get(333),
                        byteLists.get(334), byteLists.get(335));

                datDomain.setbLineExist1(bLineExist1);

                bLineExist2 = asciiToBool(byteLists.get(336), byteLists.get(337),
                        byteLists.get(338), byteLists.get(339));
                datDomain.setbLineExist2(bLineExist2);

                bLineExist3 = asciiToBool(byteLists.get(340), byteLists.get(341),
                        byteLists.get(342), byteLists.get(343));
                datDomain.setbLineExist3(bLineExist3);

               
       
                datLists.add(datDomain);// 将JavaBean添加到集合中
                
                return datLists;
            } catch (Exception e) {
                e.printStackTrace();// 抛出异常
            }
        }
        
    

        return null;


 }

 /***
  * 该方法将byte类型的数值转换成二进制的字符串
  *
  * @param b
  *            byte类型的数字
  * @return 转换后的二进制字符串
  */
 public static String byteToBinary(byte b) {
  String binary = Integer.toBinaryString(b & 0xff);

  String str = binary;// "10"
  // 8-binary.length()是需要前位补0的0的个数
  for (int i = 0; i < 8 - binary.length(); i++) {// 2需要补六个0 i<6

   str = "0" + str;
  }
  // String codeFormat="%0"+(8-binary.length())+"s";
  // binary=String.format(codeFormat, binary);
  return str;

 }

 /****
  * 将8位字节转换成ASCII码值
  *
  * @param binary
  * @return
  */
 public static char byteToAscii(String binary) {

  char[] chs = binary.toCharArray();

  int sum = 0;
  int k = 0;
  for (int i = chs.length - 1; i >= 0; i--) {
   // System.out.print(chs[i]+" ");
   sum += Integer.parseInt(chs[i] + "") * Math.pow(2, k);
   k++;
  }
  // System.out.println("sum="+sum);
  return (char) sum;

 }

 /***
  * 通过读取两个8bit的Ascii码,将他转换成c++类型的unsigned short类型,并以java 中的int类型返回
  *
  * @param byte1
  *            第一个字节的二进制
  * @param byte2
  *            第二个字节的二进制
  * @return 返回合并后的目标数字
  */
 public static int AsciiToUnsignedShort(byte byte1, byte byte2) {

  // 将二进制数转换成字符串类型并合并,获取合并后的字符串
  String addByte = byteToBinary(byte2) + byteToBinary(byte1);
  // 将合并后的字符串转换成int类型
  // 将String转换成char[]数组
  char[] byteChs = addByte.toCharArray();

  // 将char[]数组转换成int类型
  int sum = 0;
  int k = 0;
  for (int i = byteChs.length - 1; i >= 0; i--) {
   // System.out.print(chs[i]+" ");
   sum += Integer.parseInt(byteChs[i] + "") * Math.pow(2, k);
   k++;
  }
  return sum;

 }

 /****
  * 通过读取4个byte,将之转换成c++中的int类型,并返回Java中的int类型的数值
  *
  * @param byte1
  *            第一个字节
  * @param byte2
  *            第二个字节
  * @param byte3
  *            第三个字节
  * @param byte4
  *            第四个字节
  * @return 转换后的Integer类型的数据
  */
 public static int asciiToInteger(byte byte1, byte byte2, byte byte3,
   byte byte4) {

  // 将二进制数转换成字符串类型并合并,获取合并后的字符串
  String addByte = byteToBinary(byte4) + byteToBinary(byte3)
    + byteToBinary(byte2) + byteToBinary(byte1);

  // 将String转换成char[]数组
  char[] byteChs = addByte.toCharArray();

  // 将char[]数组转换成int类型
  int sum = 0;
  int k = 0;
  for (int i = byteChs.length - 1; i >= 0; i--) {

   sum += Integer.parseInt(byteChs[i] + "") * Math.pow(2, k);
   k++;
  }
  return sum;

 }

 /****
  * 将 二进制的ascii转换成c++的float数据类型,并返回Java中的float类型的数据
  *
  * @param byte1
  *            第一个字节
  * @param byte2
  *            第二个字节
  * @param byte3
  *            第三个字节
  * @param byte4
  *            第四个字节
  * @return java中的float数据类型的数值
  */
 public static float asciiToFloat(byte byte1, byte byte2, byte byte3,
   byte byte4) {
  // 将ascii转换成int类型的数据
  int i = asciiToInteger(byte1, byte2, byte3, byte4);
  return Float.intBitsToFloat(i);

 }
 
 
 /****
  * 将数据输入流转换成字符串
  * @param in 数据输入流
  * @return 返回转换后的字符串
  */
 public static String inputstream2String(InputStream in){
  
  ByteArrayOutputStream  baos=new ByteArrayOutputStream();
  byte[] buffer=new byte[1024];//每次读取1024kb个字节
  int temp=-1;
  try{
   while((temp=in.read(buffer))!=-1){
    baos.write(buffer,0,temp);
   }
   return baos.toString();
  }catch(Exception e){
   e.printStackTrace();
  }finally{
   try {
    in.close();
    baos.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   
  }
  return null;
 }
  
 
}

 

其中DatDomain是JavaBean对象,用来存储解析后的数据。

解析结果如下:

usFileHeaderLen=740
arrFileName=/Video0/Data/2018/05/16/2018-05-1612-52-04.dat
usWidth=1600
usHeight=1200
usBpp=1
usFitType=0
nGain=24
nExposureTime=20000
fC0=0.0
fC1=0.0
fC2=0.0
fC3=0.0
fC4=0.0
fC5=0.0
fC6=0.0
usTempOffset=0
usMaxHighTemp1=1500
usMaxHighTemp2=1500
usMeanTemp1=5
usMeanTemp2=5
usMeanTemp3=5
usMaxHighTemp3=1500
usMinLowTemp1=100
usMinLowTemp2=100
usMinLowTemp3=100
usLineNum=3
usPointNum=10

 

 
 
 
 
 

 

posted on 2018-05-28 15:24  以声之色,塑花之形  阅读(747)  评论(0编辑  收藏  举报

导航