IDL把一个数组写入一个二进制文件,sample
filename="/home/allen/sample"
openw,1,filename,/F77_UNFORMATTED
a=[1L,3L,5L,7L,9L,11L,19L] ;IDL中的Long就是C语言中32位的int(64位机器上至少是这样)
writeu,1,a ;36 byte = 4 byte * 9, 如果没有F77_UNFORMATTED关键字则是28 byte
close,1
end
IDL读取一个二进制文件,sample
filename="/home/allen/sample"
openr,2,filename,/F77_UNFORMATTED
a=lonarr(7)
readu,2,a
print,a
close,2
end
用C读取该二进制文件并输出
#include<stdio.h>
int main()
{
FILE *fd;
int integer[10],flag,i;
if(fd=fopen("sample","rb"))
{
flag=fread(integer,sizeof(int),9,fd);
}
for(i=0;i<flag;i++)
{
printf("%d\n",integer[i]);
}
return 0;
}
allen@xps:~$ ./read_binary
28
1
3
5
7
9
11
19
28
从这个输出结果中可以看到, 这里IDL采用的写入二进制文件的方法会自动在两端
保存数据的总长度, 长度计算公式为
4 byte×7=28 byte
, 所以会在数据的头和尾出现多余的校验数据28
改进上面的C代码以便正确利用校验值:
#include<stdio.h>
int main()
{
FILE *fd;
int integer[7],flag,i,dummy0,dummy1;
if(fd=fopen("sample","rb"))
{
fread(&dummy0,sizeof(int),1,fd); //如果读取较多,可考虑将这句和下下句改成宏
flag= fread(integer,sizeof(int),7,fd);
fread(&dummy1,sizeof(int),1,fd);
}
if(dummy0!=flag*4 || dummy1!=flag*4)
{
puts("read error, exit!");
return -1;
}
for(i=0;i<flag;i++)
{
printf("%d\n",integer[i]);
}
fclose(fd);
return 0;
}
//用C语言写入二进制数据可以用函数fwrite,用法和fread相似.
//size_t 就是 unsigned int
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
作为对比, 以下是IDL普通ASCII文件的读写
;write
filename="/home/allen/sample-ascii"
openw,1,filename
a=[1L,3L,5L,7L,9L,11L,19L]
printf,1,a
close,1
end
;read
filename="/home/allen/sample-ascii"
openr,2,filename
a=lonarr(7)
readf,2,a
print,a
close,2
end
作为对比, 以下是没有f77_unformatted
关键字的IDL二进制输入/输出时, C代码修改后应该的样子(其实这样子更方便, 只是没有了对fortran的兼容性和一点点安全性, 但是我不在乎!)
#include<stdio.h>
int main()
{
FILE *fd;
int integer[7],flag,i;
if(fd=fopen("sample","rb"))
{
flag= fread(integer,sizeof(int),7,fd);
}
for(i=0;i<flag;i++)
{
printf("%d\n",integer[i]);
}
fclose(fd);
return 0;
}