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文件的一個特點

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章