首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >endianness是否会影响写入奇数字节?

endianness是否会影响写入奇数字节?
EN

Stack Overflow用户
提问于 2019-01-08 11:47:56
回答 3查看 500关注 0票数 1

假设您有一个uint64_t bytes,并且您知道只需要7个字节,因为存储的整数不会超过7个字节的限制。

在编写文件时,您可以执行以下操作

std::ofstream fout(fileName); fout.write((char *)&bytes, 7);

只写7个字节。

我想弄清楚的问题是,系统的安全性是否会影响写入文件的字节。我知道endianess会影响字节的写入顺序,但它是否也会影响写入的字节呢?(只适用于写入字节比整数通常少的情况。)

例如,在一个小的endian系统上,头7个字节被写入文件,从LSB开始。在大终端系统中,什么是写入文件的?

或者换句话说,在一个小的endian系统上,MSB(第8字节)没有写入文件。我们能期望在一个大终端系统上出现同样的行为吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-01-08 12:10:26

代码语言:javascript
运行
复制
uint64_t bytes = ...;
fout.write((char *)&bytes, 7);

这将准确地写7个字节,从&字节的地址开始。但是,LE和BE系统之间的不同之处在于内存中的八个字节是如何排列的(假设变量位于地址0xff00):

代码语言:javascript
运行
复制
            0xff00  0xff01  0xff02  0xff03  0xff04  0xff05  0xff06  0xff07
LE: [byte 0 (LSB!)][byte 1][byte 2][byte 3][byte 4][byte 5][byte 6][byte 7 (MSB)]
BE: [byte 7 (MSB!)][byte 6][byte 5][byte 4][byte 3][byte 2][byte 1][byte 0 (LSB)]

如果转换为char*,那么启动地址(0xff00)不会改变,您将在这个地址上打印出字节,再加上接下来的六个地址--在这两种情况下(LE和BE),地址0xff07都不会被打印。现在,如果您查看上面我的内存表,很明显,在be系统上,您在存储MSB时丢失了LSB,MSB不包含信息.

在BE系统上,您可以编写fout.write((char *)&bytes + 1, 7);。但是,请注意,这仍然留下了一个可移植性问题:

代码语言:javascript
运行
复制
fout.write((char *)&bytes + isBE(), 7);
//                           ^ giving true/false, i. e. 1 or 0
// (such function/test existing is an assumption!)

这样,由BE-System编写的数据在回读时会被LE-system误解,反之亦然。安全版本将像盖萨在其回答中所做的那样,对每个字节进行分解。为了避免多个系统调用,您可以将值分解为一个数组,然后打印出来。

如果在linux/BSD上,也有一个不错的替代方案

代码语言:javascript
运行
复制
bytes = htole64(bytes); // will likely result in a no-op on LE system...
fout.write((char *)&bytes, 7);
票数 1
EN

Stack Overflow用户

发布于 2019-01-08 11:51:13

恩典只影响(16,32,64) int的书写方式。如果您正在编写字节(这是您的情况),它们将按照与您所做的完全相同的顺序编写。

例如,这种写作方式会受到以下因素的影响:

代码语言:javascript
运行
复制
std::ofstream fout(fileName);
int i = 67;
fout.write((char *)&i, sizeof(int));
票数 2
EN

Stack Overflow用户

发布于 2019-01-08 12:12:04

我想弄清楚的问题是,系统的安全性是否会影响写入文件的字节。

是的,它会影响到写入文件的字节。

例如,在一个小的endian系统上,头7个字节被写入文件,从LSB开始。在大终端系统中,什么是写入文件的?

前7个字节被写入文件。但这一次从MSB开始。所以,最后,最低的字节是而不是写入文件,因为在大终端系统中,最后一个字节是最低字节。

所以,这不是你想要的,因为你失去了信息。

一个简单的解决方案是将uint64_t转换为小endian,并编写转换后的值。或者用一种小的endian系统会编写它的方式逐字节地编写值:

代码语言:javascript
运行
复制
uint64_t x = ...;

write_byte(uint8_t(x));
write_byte(uint8_t(x>>8));
write_byte(uint8_t(x>>16));
// you get the idea how to write the remaining bytes
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54091194

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档