如何读取和写入许多对象(或任何数据)到缓冲区
How to read and write many objects (or any data) to a buffer?
我正在写一个程序来保存一些对象(结构体)到缓冲区。我没有实验写很多对象到缓冲区和读取这些对象从缓冲区。任何帮助都会很感激。我的代码可以写一个项目到对象,我想写多个对象到缓冲区
struct PointFull {
double lat;
double lon;
};
PointFull item1;
PointFull item2;
PointFull item3;
PointFull item4;
PointFull item5;
void* buffer = malloc(sizeof (PointFull));
int fd = open("output", O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR);
if (fd < 0) {
printf("Error opening filen");
return 1;
}
//The below function can write only one item to buffer. How to write 5 item (from item1 to item5) to the buffer
//memcpy(buffer, &item1, sizeof (item));
write(fd, buffer, sizeof (item));
现在我在硬盘上有一个名为"output"的文件,然后我想读取该文件以测试数据。
int fd2 = open("output", O_RDONLY, S_IWUSR | S_IRUSR);
if (fd2 < 0) {
printf("Error opening filen");
return 1;
}
void* bufferRead;
bufferRead = malloc(5* sizeof (PointFull));
read(fd2, bufferRead,sizeof (PointFull));
目前,我有bufferRead包含5项,但我不知道如何读取缓冲区插入数据结构??请帮帮我!
你要做的是序列化。假设你有这样的结构:
struct PointFull {
int lat;
int lon;
};
和
PointFull item1, item2;
序列化到缓冲区的方式是:
unsigned char arr[20] = {0};
memcpy(arr, &item1.lat, sizeof(int));
memcpy(&arr[1 * sizeof(int)], &item1.lon, sizeof(int));
memcpy(&arr[2 * sizeof(int)], &item2.lat, sizeof(int));
memcpy(&arr[3 * sizeof(int)], &item2.lon, sizeof(int));
我这样序列化是因为直接像你建议的那样写结构不是一个好主意,因为填充问题。结构可能有填充物,它们可能因系统而异。
现在,您有了字节数组(包含两个PointFull
对象-对于更多对象,您将遵循类似的方法),您可以在write中使用它:
write(fd, arr, 20);
读取字节数组后,您可以使用类似的memcpy
调用来重建点对象(现在只是目的地将是点对象成员)。但这样做的问题是,二进制的整数序列化是不可移植的(而且是浮点数)——在不同的系统上,整数可能有不同的大小和不同的端序。对于浮点数,它们的表示也可能不同。
无论如何,有一种方法如何在二进制中编码浮点数-检查pack754
(和类似的解包)功能。如果你使用这个函数序列化字节数组中的浮点数,并像这个答案一样分别序列化每个浮点数,那么你可能会没事。
<子> p。这是一个解释序列化的帖子(对于浮点编码部分,您可以在我的回答中使用链接)子>
如果你只想在文件中写入结构,你可以直接写入它们:
write(fd, &item1, sizeof (item1));
write(fd, &item2, sizeof (item2));
...
除非你真的有很多这样的文件,否则它会表现得很好,操作系统本身会缓冲文件系统访问。
如果你真的想使用一个缓冲区,你可以有一个小类来写缓冲区:
class BufferWriter {
char *ptr;
int current;
public:
BufferWriter( void *ptr ) : ptr((char*)ptr), current(0) {}
template<typename T>
void Write( const T &t ) {
memcpy(&ptr[current], &t, sizeof(t) );
current += sizeof(t);
}
int GetTotalLength() {
return current;
}
};
然后像这样使用:
char *b = new char[ENOUGH];
BufferWriter buffer(b);
buffer.Write(item1);
buffer.Write(item2);
...
write(fd, b, buffer.GetTotalLength());
delete[] b;
如果你愿意,你可以添加一些代码来检查缓冲区溢出。
关于您输出的文件的可移植性(如果您计划将其传输到另一个设备上),您可能希望使用intX_t
(例如:int32_t
)而不是int
, short
或其他确定大小的文件。同样对于int,您可能需要检查系统的端序,但在个人设备上它将始终是小端序。您不必担心float
和double
,因为所有现代设备都使用IEEE 754规范,甚至大多数外来设备也坚持此规范。
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 从多个源构造一个对象,包括一个对象向量
- 如何在C++中从文件中读取/写入多个对象
- 最多获取2个对象
- 对象实例化调用构造函数的次数太多
- 通过switch和static_cast访问多态对象的运行时类型
- 无法使用VAO和EBO(openGL)绘制多个对象
- 如何创建指针链?我想创建具有指向更多对象的指针的对象,该对象具有指针.这可能吗?
- 初始化多对象双对象<矢量<矢量<float>> >
- 使用OpenGL绘制更多对象时,性能会降低
- 多对象手写单链表中的分段错误
- 游戏项目的多对象类型容器或动态铸造
- 单个多对象卡尔曼滤波器与多个单对象卡尔曼滤波器(多个)
- C++ 将数组打印到任何输出对象(按函数)
- 仅通过指针强制转换使类类型可互换,而无需分配任何新对象
- opencv 卡尔曼滤波多对象跟踪错误
- 增强多对象序列化
- 多对象绘制(OpenGL)
- 是否可以将任何类对象作为测试表达式传递给任何测试表达式,例如if,while like ifstream对象
- 在任何全局对象之前初始化