IDL/C 二进制数据的读取和写入

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;
}

延伸阅读
IDL读写F77_UNFORMATTED文件的一个特点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值