golang保存二进制文件会有大小端问题吗

golang保存二进制文件会有大小端问题吗,第1张

golang保存二进派培制文件会有大小端问题。

这个二进制文件的确有Big Endian 和Little Endian的问题,这个与CPU指令体系有关,不过不用 *** 心,像JPEG就是Big Endian,其编解码就都是按照这个约定来完成的,没有平台问题,也没有大小端的问题。

编译centos上的可执行文件的时候需要握桥交叉编译。golang的交叉编译很容易尘皮唯,你的情况的话用下面这条命令,GOOS=linux GOARCH=amd64 go build ./文件。

golang描述:

Go的语法接近C语言,但对于变量的声明有所不同。Go支持垃圾回收功能。Go的并行模型是以东尼·霍尔的通信顺序进程(CSP)为基础。

采取类似模型的其他语言包括Occam和Limbo,但它也具有Pi运算的特征,比如通道传输。在1.8版本中开放插件(Plugin)的支持,这意味着现在能从Go中动态加载部分函数。

与C++相比,Go并不包括如枚举、异常处理、继承、泛型、断言、虚函数等功能,但增加了 切片(Slice) 型、并发、管道、垃圾回收、接口(Interface)等特性的语言级支持。Go 2.0版本将支持泛型,对于断言的存在,则持负面态度,同时也为自己不提供类型继承来辩护。

先看下面的代码,然后我在简短的解释一下。

#include <拍扒stdio.h>#include <stdlib.h>#include <string.h>#include <string>#define nmemb 7/****************************************************

 Date types(Compiler specific) 数据类型(和编译器相关)

*****************************************************/typedef unsigned char uint8     /* Unsigned 8 bit quantity  */typedef signed char int8        /* Signed 8 bit quantity    */typedef unsigned short uint16   /* Unsigned 16 bit quantity */typedef signed short int16      /* Signed 16 bit quantity   */typedef unsigned int uint32     /* Unsigned 32 bit quantity */typedef signed int int32        /* Signed 32 bit quantity   */typedef float fp32              /* Single precision         */

                                 /* floating point        袭旅昌   */typedef double fp64             /* Double precision         */

                                 /* floating point           *///int32#define BigtoLittle32(A)   ((( (uint32)(A) &0xff000000 ) >>24) | \

                                              (( (uint32)(A) &0x00ff0000 ) >>8)   | \

                                              (( (uint32)(A) &0x0000ff00 ) <<8)   | \

                       镇袜                       (( (uint32)(A) &0x000000ff ) <<24))//int16#define BigtoLittle16(A)   (( ((uint16)(A) &0xff00) >>8 )    | \

                           (( (uint16)(A) &0x00ff ) <<8))/************************************************************

*     Conversion little endian float data to big endian

*     *************************************************************/float ReverseFloat(const float inFloat)

{    float retVal   char *floatToConvert = (char*) &inFloat   char *returnFloat = (char*) &retVal   // swap the bytes into a temporary buffer

   returnFloat[0] = floatToConvert[3]

   returnFloat[1] = floatToConvert[2]

   returnFloat[2] = floatToConvert[1]

   returnFloat[3] = floatToConvert[0]   return retVal

}struct matrix

{    int row   int column

}s[nmemb]void set_s(int j, int x, int y)

{

   s[j].row = x

   s[j].column = y

}bool is_bigendian()

{    int a = 0x1234   char b =  *(char *)&a //b == the Low address part of a

   //printf("%c\n", b)

   if (b == 0x34) {        return false

   }    return true

}int main()

{    if (is_bigendian()) {        printf("BigEndian\n")

   } else {        printf("LittleEndian\n")

   }

   FILE *fp

   set_s(0, 1, 50)

   set_s(1, 1, 80)

   set_s(2, 4, 20)

   set_s(3, 50, 1)

   set_s(4, 80, 2)

   set_s(5, 100, 3)

   set_s(6, 100, 4)   int ans = sizeof(struct matrix)   printf("size: %d\n", ans)   printf("size: %d\n", sizeof(s))   if ((fp = fopen("test", "wb")) == NULL) {        printf("EROOR\n")       return 1

   }    for (int j = 0j <nmemb++j) {        printf("row: %d   column: %d\n", s[j].row, s[j].column)

   }

   fwrite(s, sizeof(struct matrix), nmemb, fp)   for (int i = 0i <nmemb++i) {        float *m = (float*) malloc(sizeof(float) * s[i].row * s[i].column)

       bzero(m, sizeof(float) * s[i].row * s[i].column)       for (int j = 0j <s[i].row++j) {            for (int k = 0k <s[i].column++k) {

               m[k + j*s[i].column] = k

           }

       }

       fwrite(m, sizeof(float), s[i].row * s[i].column, fp)       free(m)

   }

   fclose(fp)   printf("11\n")   /*

   printf("%d\n", sizeof(float))

   FILE *fp

   if ((fp = fopen("test", "rb")) == NULL) {

       printf("EROOR\n")

       return 1

   }

   fread(s, sizeof(struct matrix), nmemb, fp)

   for (int i = 0i <nmemb++i) {

       printf("row: %d   column: %d\n", s[i].row, s[i].column)

   }

   for (int i = 0i <nmemb++i) {

       float *m = (float*) malloc(sizeof(float) * s[i].row * s[i].column)

       bzero(m, sizeof(float) * s[i].row * s[i].column)

       fread(m, sizeof(float), s[i].row * s[i].column, fp)

       for (int j = 0j <s[i].row++j) {

           for (int k = 0k <s[i].column++k) {

               printf("%lf ", m[k + j*s[i].column])

           }

           printf("\n")

       }

       printf("\n\n")

       free(m)

   }

   fclose(fp)

   */

   return 0

}

fopen和fclose是很常见的,在这里就不做解释了。我们来看看fwrite和fread,本来以为这个很麻烦,但是用过之后发现这个二进制文件读写才是最简单的。

size_t fwrite(const void * ptr,size_t size,size_t nmemb,FILE * stream)

fwrite()用来将数据写入文件流中。

stream为已打开的文件指针

ptr 指向欲写入的数据地址

写入的字符数以参数size*nmemb来决定。

size表示写入一个nmemb的内存大小。

fwrite()会返回实际写入的nmemb数目。

size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream)

fread()用来从文件流中读取数据。

stream为已打开的文件指针

ptr 指向欲存放读取进来的数据空间

读取的字符数以参数size*nmemb来决定

size表示读取一个nmemb的内存大小。

fread()会返回实际读取到的nmemb数目,如果此值比参数nmemb 小,则代表可能读到了文件尾或有错误发生,这时必须用feof()或ferror()来决定发生什么情况。

返回实际读取到的nmemb数目。

详情参见上面的代码。

另外就是大小端的问题了。关于大小端的具体解释网上有很多,在此不作解释。参考上面写的代码,我判断了自己机器是大端还是小端,并且实现了int16,int32已经float数据类型的大小端转换,大端转小端,在使用相同的代码一次小端又变成了大端。

PS:float的大小端转化我之前一直以为写的是错的,因为好多数据转化之后输出都是0。后来发现可能是与float类型在内存中的存放有关,我们的程序是对的。

1、二进制文本使用fopen函数的二进制模式“rb”就可以打开。对于程序来说,不管后缀名如何,文件分为两种类型:文本文件和二并运进制文仿蔽梁件。 C语言备运里有一系列文件 *** 作函数。区分文本和二进制文件,需要在打开文件时设置不同的控制符mode的变量即可。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12224746.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-22
下一篇 2023-05-22

发表评论

登录后才能评论

评论列表(0条)

保存