c++这个将对象写入二进制文件
c++ this to write object into binary file
我在c++函数中遇到了一些指针问题。我会把我的类写进二进制文件,所以我写这个函数成员
void Product::saveProducts(){
fstream file;
Product temp;
temp.setId(-1);
bool flag = false;
file.open("cigarettes.dat", ios::out | ios::binary);
if(file.is_open()){
file.seekg(0, ios::end);
if(file.tellg()!=0){
file.seekg(0, ios::beg);
while(!file.eof()){
file.read(reinterpret_cast<char *>(&temp), sizeof(temp));
if(temp.getId() == this->getId()){
flag=true;
file.seekp(-sizeof(temp),ios::cur);
file.write(reinterpret_cast<char *>(this), sizeof(temp));
break;
}
}
}
if(!flag){
file.write(reinterpret_cast<char *>(this), sizeof(temp));
}
}
file.flush();
file.close();
}
但是当我试图用另一个功能成员检索我存储的对象时:
list<Product> Product::loadProducsts(){
fstream file;
Product temp;
list<Product> products;
file.open("cigarettes.dat", ios::in | ios::binary);
if(file.is_open()){
while(!file.eof()){
file.read(reinterpret_cast<char *>(&temp), sizeof(temp));
products.push_front(temp);
}
}
file.close();
return products;
}
我的数组只填充了一个空对象。怎么了?
您的代码有很多问题,从事实上,仅仅向文件转储位通常不会给你任何有用的东西,你可以读回。事实上你需要reinterpret_cast
才能使用它应该会给你小费关闭。此外:
-
您只打开文件进行输出,然后尝试从(打开一个文件进行输出会截断它,所以您已经丢失了您以前的所有数据。)
-
我不确定你认为你在用
while (!file.eof())
做什么,但这肯定是不对的。如果出于某种原因file.read
在没有到达文件末尾的情况下失败,您将以例如,在一个无休止的循环中。 -
并且您使用的是
file.read
的结果而未进行验证功能正常。 -
您关闭文件时不在末尾。这会截断以输出模式打开的文件。
-
第二个代码段的读取循环中也存在同样的问题。如果文件为空,您仍将"读取"一个对象,并按下默认将CCD_ 5构造为CCD_。
不知道Product
是什么样子,也不知道最初的内容关于文件,很难说真正发生了什么。但是最有可能:
-
打开时截断文件。它现在的长度为0.
-
由于
file.tellg()
返回0
,您甚至从未尝试过读取(如果你试图阅读它,就会设置一个错误,这将使所有连续的操作都没有操作。) -
然后编写单个元素,并关闭文件。
我唯一不太确定的是:在这种情况下实际上包含一个元素。所以当你试着读的时候,第一个file.read
成功,可能没有设置eofbit
,因为file.read
不需要任何展望。如果eofbit
未设置,我希望您再次循环,并将CCD_ 14中未修改的比特每秒推送到CCD_时间
编辑:
FWIW:如果我们假设您处于非常受限的情况其中仅将数据位写入磁盘是有效的(通常意味着你稍后会在同一时间重读它们进程,但从不来自不同的进程),和在有效的Product
中,id
永远不可能是-1,你可能想要做的是:
Product temp;
temp.setId( -1 ); // This sort of thing should really be handled by a constructor
std::fstream file( "cigartettes.dat", ios::out | ios::in | ios::binary );
while ( file.read( reinterpret_cast<char*>( &temp ), sizeof(temp) && temp.getId() != getId() ) {
}
if ( file.gcount() != 0 ) {
// Error somewhere, we ended up reading a partial record
} else if ( temp.getId() == getId() ) {
file.seekp( -static_cast<int>( sizeof(temp) ) );
} else {
file.clear();
file.flush();
}
file.write( reinterpret_cast<char const*>( this ), sizeof(*this) );
file.close();
if ( !file ) {
// Something went wrong somewhere...
}
几个评论:
输入和输出都需要打开。仅打开in输出意味着1)文件将被截断,2)任何尝试读取它将失败。
如果
file.read
无法读取正确的字节。如果失败,它可能已经读取了一些字节(并且覆盖Product
中的id字段,并保留当前指向某个位置的指针,该位置不是对象的模尺寸)。因此,您应该使用file.gcount()
(返回最后一次未格式化的读取操作—在读取的情况下你正在做的,这只能与sizeof(Product)
不同如果读取失败。当指定负值向后查找时:在执行之前将
sizeof
的结果转换为签名类型即CCD_ 23。否则,你会得到一些天文数字积极的价值,这将导致你尝试超越文件结尾(将失败)。当读取失败,并且读取的字节数为0时已到达文件末尾。并设置
failbit
导致未来所有操作失败。所以我们必须清除错误,如果我们要写以扩展数据。(如果我们还没有到达文件的末尾,当然,没有什么可以清除。)进行双向输入时,在读取之后,必须执行写入前的查找或刷新。(不要问我为什么;这正是标准所说的。)
最后,最好验证文件的状态关闭后,当所有缓冲区都已完全冲洗,并且传递给操作系统。如果由于某种原因,写入失败在某个地方,你想知道它,通知用户输出的文件已损坏。
我可以补充一下,在文件是将文件复制到新文件,替换或追加更改后的记录,然后删除旧文件并重命名新尝试修改文件可能意味着如果出了问题,你就会丢失所有的数据。
- 对在不同二进制文件中创建的对象文件的依赖关系
- 如何将包含另一个对象向量的对象保存到文件中,并使用C++中的二进制文件从文件中读回?
- 使用此指针在 c++ 中将对象写入二进制文件
- 将对象信息保存到二进制文件中
- 如何使用自定义对象的序列化在 c++ 中编写自定义二进制文件处理程序
- C#将类对象写入二进制文件
- C++/Python 中对象和结构的二进制文件结构
- 将对象(指针)在地图中输出到二进制文件
- 未显式引用对象的全局对象构造函数在最终二进制文件 - LD 中被丢弃
- 使用 C++ 将对象读取和写入二进制文件
- 正在从二进制文件中读取对象列表
- C++ - 如何编写和读取包含对象的结构?(写入和读取二进制文件)
- C++ 将对象写入二进制文件
- 将二进制文件的一部分读入预先存在的basic_string对象
- 如何像二进制文件一样读取提升mapped_region对象
- CMake:从外部项目链接共享C++对象会生成具有相对路径的二进制文件,而不是绝对路径
- c++这个将对象写入二进制文件
- c++将对象写入和读取到二进制文件中
- 将二进制文件用于复杂对象C++
- 将对象数组写入和读取到二进制文件