您的位置:首页 > 编程语言 > Java开发

用java语言读取和写人c语音的结构体数据

2016-03-25 22:41 302 查看
最近因为要把excel文件的表格数据保存成一个用结构体格式写成的二进制文件,于是研究了一下如何用java来访问二进制数据。

原先的结构体是用c语言来访问的,因为c语言支持结构体指针,因此要访问结构体数据只需要用结构体指针指向数据的入口地址,就可以用->符号把结构体的元素逐一取出来,同样,写入结构体的元素也很方便。

我原先以为在java里面也会有同样的操作方式,结果有点失望,java下面是不能进行这样的操作的。那么如果有一个用c语言代码写的程序保存起来的这样的结构体数据文件,在java里面应该如何访问呢?

假设有一个二进制文件,里面存放了一个这样的结构体:

typedef struct tagSingerType
{
U08	            recordFlag;
U08	            recordLen;
U16	            TypeSum;
char	        singerType[STRING_MAX];
}SingerType_s;


那么我们首先把文件读进来,存放到一个byte型的数组里,

in = new FileInputStream(file);
DataInputStream dis=new DataInputStream(in);
int fileSize = (int)file.length();
byte data[] = new byte[fileSize];
int i = 0;
while(dis.available()>0){
i = dis.read(data);
}
parseBuffer(data);
接下来就是分析数据:

singerType.recordFlag = ReadIdxFile.getByteValue(b, pos);
singerType.recordLen = ReadIdxFile.getByteValue(b, pos + 1);
singerType.TypeSum = ReadIdxFile.getShortValue(b, pos+2, pos+4);
int stringLen = singerType.recordLen - SINGER_FIX_LEN;
singerType.singerTpye = ReadIdxFile.getStrValue(b, pos+4, pos+SINGER_FIX_LEN+stringLen);
其中调用的几个基本方法,是把数组里的字节一个一个取出来:

获取整型,就相当于取4个字节,short型为2个字节,byte是一个字节,字符串是根据具体的长度来取。
public static int getIntValue(byte [] b,int s,int e)
{
int nR=0;
if(s+3<e)
{
nR = b[s] & 0xff;
nR = nR + ( b[s+1]<<8  & 0x0000ff00 );
nR = nR + ( b[s+2]<<16 & 0x00ff0000 );
nR = nR + ( b[s+3]<<24 & 0xff000000 );
}

return nR;
}

public static int getShortValue(byte [] b,int s,int e)
{
int nR=0;
if(s+1<e)
{
nR = b[s] & 0xff;
nR = nR + ( b[s+1]<<8  & 0x0000ff00 );
}

return nR;
}

public static int getByteValue(byte [] b,int s)
{
int nR=0;

nR = b[s] & 0xff;
return nR;
}

public static String getStrValue(byte[] b,int s,int e)
{
byte[] tb=new byte[e-s+1];
int i=0;
for(byte ee:tb)
{
tb[i++]=0;
}

i=0;
for(byte ee:b)
{
if(i>=s && i<e)
{
tb[i-s]= b[i];
}
else if(i>=e)
{
break;
}
i++;
}
String r=new String(tb);
return r;
}


然后,如果想用java保存一个结构体模样的二进制文件,就需要反过来操作。

首先定义几个基本的操作方法:

public static void valuecpy(byte[] b,int s,int e,String msg){
byte cs[] = msg.getBytes();
for(byte c : cs){
b[s] = c;
s++;
if(s >= e){
System.out.println("reach end of array");
break;
}
}
}

public static void valuecpy(byte[] b,int start, int end,int nValue){
b[start]  =(byte)(nValue&0x000000ff) ;
b[start+1]=(byte)( (nValue&0x0000ff00) >> 8) ;
b[start+2]=(byte)( (nValue&0x00ff0000) >> 16) ;
b[start+3]=(byte)( (nValue&0xff000000) >> 24) ;
}

public static void valuecpy(byte[] b,int start, int end,short nValue){
b[start]  =(byte)(nValue&0x000000ff) ;
b[start+1]=(byte)( (nValue&0x0000ff00) >> 8) ;

}


由于java支持重载,所以方法名是一样的,只是参数不一样,为了省事一点,对于byte数据我就直接赋值,没有专门写一个方法。

接下来的做法是:

public void copyToBuf(byte b[]){
b[0] = (byte) this.recordFlag;
b[1] = (byte) this.recordLen;
ReadIdxFile.valuecpy(b, 2, 3, this.TypeSum);

ReadIdxFile.valuecpy(b, 4, this.recordLen, this.singerTpye);

}
通过这个方法,把数据赋值到byte b[]里面,然后再把数据写入文件,就相当于保存了一个结构体了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: