Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将多个对象(或任何数据)读写到缓冲区?_C++_Buffer_Readfile_Writefile - Fatal编程技术网

C++ 如何将多个对象(或任何数据)读写到缓冲区?

C++ 如何将多个对象(或任何数据)读写到缓冲区?,c++,buffer,readfile,writefile,C++,Buffer,Readfile,Writefile,我正在编写一个程序,将一些对象(结构)保存到缓冲区。我没有将许多对象写入缓冲区并从缓冲区读取这些对象的实验。任何帮助都将不胜感激。 我的代码可以将一个项写入对象,我希望将多个对象写入缓冲区 struct PointFull { double lat; double lon; }; PointFull item1; PointFull item2; PointFull item3; PointFull item4; PointFull item5; void* 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 file\n");
    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));
struct PointFull{
双lat;
双离子;
};
完整项目1;
完整项目2;
完整项目3;
完整项目4;
完整项目5;
void*buffer=malloc(sizeof(PointFull));
int fd=开放(“输出”,O|u WRONLY | O|u CREAT,S|u IWUSR | S|u IRUSR);
如果(fd<0){
printf(“打开文件时出错”);
返回1;
}
//下面的函数只能将一项写入缓冲区。如何将5项(从item1到item5)写入缓冲区
//memcpy(缓冲区和项目1,大小(项目));
写入(fd、缓冲区、sizeof(项));
现在我在硬盘中有一个名为“output”的文件,然后我想读取该文件以测试数据

    int fd2 = open("output", O_RDONLY, S_IWUSR | S_IRUSR);
if (fd2 < 0) {
    printf("Error opening file\n");
    return 1;
}
void* bufferRead;
bufferRead = malloc(5* sizeof (PointFull));
read(fd2, bufferRead,sizeof (PointFull));
int fd2=open(“输出”,仅限O_RDONLY,S_IWUSR | S_IRUSR);
if(fd2<0){
printf(“打开文件时出错”);
返回1;
}
void*bufferRead;
bufferRead=malloc(5*sizeof(PointFull));
读取(fd2,bufferRead,sizeof(PointFull));

目前,我有bufferRead包含5项,但我不知道如何读取buffer以将数据插入结构???请帮帮我

您要做的是序列化。假设你有这样的结构:

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(fd, arr, 20);
在读取字节数组之后,您可以通过使用类似的
memcpy
调用来重构点对象,就像上面所说的那样(现在的目标就是点对象成员)。但问题是二进制中的整数序列化是不可移植的(而且是浮动的)——在不同的系统上,整数可能有不同的大小、不同的endianness。 此外,对于浮动,它们的表示形式可能会有所不同

无论如何,有一种方法可以在二进制检查
pack754
(以及类似的解包)函数中对浮点进行编码。如果您使用该函数序列化字节数组中的浮点,并像下面的回答那样分别序列化每个浮点,那么您可能就没事了


这里的文章解释了序列化(对于浮点编码部分,您可以在我的回答中使用link)。

如果您只想将结构写入文件,您可以直接写入:

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;
    }
};
如果需要,可以添加一些代码来检查缓冲区溢出


关于您输出的文件的可移植性(如果您计划将其传输到另一个设备),您可能希望使用
intX\u t
(例如:
int32\u t
)而不是
int
short
或任何确保大小的方法。同样对于INT,您可能需要检查系统的endian,但在个人设备上,它将始终是little endian。您不必担心
float
double
,因为所有现代设备都使用IEEE 754标准,甚至大多数外来设备也遵循这一标准。

在您的第一个示例中,如何使用数组,如
PointFull items[5]
?如果你想使用C++,那么使用<代码>新< /COD>,而不是<代码> MalcC < /Calp>!@!谢谢你的回复。在我的情况下,我想写一个对象,过了很长一段时间,我需要写另一个对象,所以我不能使用数组。我想依次写对象。你是否有任何想法:如果你使用C++,你可以使用Boost序列化。在下面的链接中查找boost/archive以获得一个简单的示例:感谢您的回复。我有一个问题,你为什么要用arr[]写lon-lat?我可以将整个项目写入arr[]吗?memcpy(&arr[1*sizeof(PointFull)],&item1,sizeof(PointFull))@缅因州ậtT–n:我已经提到了——因为填充问题。搜索结构填充我找到了。现在,我有了文件,如何从文件中读取项目。为一个项目使用每个缓冲区?@MaiNhậtT–n:还要检查我提供的链接。你读的也一样。将整个文件读取到字节数组。然后从数组do memcpy到每个对象的成员,如
memcpy(&item1.lat、arr、sizeof(int))等等。类似地,就像您在写时所做的那样,只是在memcpy中使用read更改顺序
char *b = new char[ENOUGH];
BufferWriter buffer(b);

buffer.Write(item1);
buffer.Write(item2);
...

write(fd, b, buffer.GetTotalLength());
delete[] b;