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的变量即可。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)