读写同一个文件c++
reading and writing to the same file c++
我有一个小应用程序,它在开始时会读取文本文件(带有序列化对象),其中我存储了一些对象(我通过重载 << 和 >> 运算符来实现)。每次创建新对象时都必须更新此文本文件:
fstream m_haystackMapFile;
m_haystackMapfile.open(haystackMapFile, std::ios::binary | std::ios::in | std::ios::out);
首先我读了:
WHaystackFile f;
m_haystackMapfile.seekg(0, std::ios::beg);
std::copy(std::istream_iterator<WHaystackFile>(m_haystackMapfile), std::istream_iterator<WHaystackFile>(), std::back_inserter(m_haystackFiles));
std::cout << "reading input file, no of files: " << m_haystackFiles.size() << std::endl;
for(std::vector<WHaystackFile>::iterator it = m_haystackFiles.begin(); it != m_haystackFiles.end(); ++it){
f = *it;
std::cout << "key: " << f.getKey() << " cookie: " << f.getCookie() << " path: " << f.getPath() << " size: " << f.getSize()<< std::endl;
}
然后在创建新对象后我写:
void WhaystackMap::addEntry(WHaystackFile &f){
std::cout << "adding entry to index file" << std::endl;
m_haystackMapfile.seekp(std::ios::end);
m_haystackMapfile << f;
std::cout << f;
}
不幸的是,我想写入的文件永远不会更新,它的大小始终为 0。也许我搞砸了一些东西,但在谷歌搜索后我找不到答案如何使用 fstream 我可以读取和写入同一个文件...
欢迎任何帮助:)
问候
J.
问题是 seekp()
的错误用法:
- 您在
m_haystackMapfile.seekp(std::ios::end)
中使用一个参数 ios::end
- 但单一参数仅适用于绝对定位。所以
ios::end
被转换成一个整数,并且会把你定位在一个意想不到的地方(在我的实现中它是 2)。
- 你必须使用
m_haystackMapfile.seekp(0, std::ios::end)
而不是
还有另一个问题:您在 std::copy()
中使用的 istream_iterator<>()
将读取流直到它结束。所以 failbit 和 eofbit 将被设置。
因此,在您清除标志之前,任何流操作都不会成功:m_haystackMapfile.clear();
检查 I/O 操作是否成功非常重要。例如,如果seekp
无法定位到想要的位置,它会设置failbit
,然后所有后续写入都会失败。或者,正如@Christophe 指出的那样,如果您将文件读到最后,您将导致 eofbit 被设置。除非清除该位,否则下一个 I/O 操作(甚至 seekp)将失败。
即使 eofbit 已被重置,查找也可能会失败,因为调用应该是 m_haystackMapfile.seekp(0, std::ios::end);
.
我有一个小应用程序,它在开始时会读取文本文件(带有序列化对象),其中我存储了一些对象(我通过重载 << 和 >> 运算符来实现)。每次创建新对象时都必须更新此文本文件:
fstream m_haystackMapFile;
m_haystackMapfile.open(haystackMapFile, std::ios::binary | std::ios::in | std::ios::out);
首先我读了:
WHaystackFile f;
m_haystackMapfile.seekg(0, std::ios::beg);
std::copy(std::istream_iterator<WHaystackFile>(m_haystackMapfile), std::istream_iterator<WHaystackFile>(), std::back_inserter(m_haystackFiles));
std::cout << "reading input file, no of files: " << m_haystackFiles.size() << std::endl;
for(std::vector<WHaystackFile>::iterator it = m_haystackFiles.begin(); it != m_haystackFiles.end(); ++it){
f = *it;
std::cout << "key: " << f.getKey() << " cookie: " << f.getCookie() << " path: " << f.getPath() << " size: " << f.getSize()<< std::endl;
}
然后在创建新对象后我写:
void WhaystackMap::addEntry(WHaystackFile &f){
std::cout << "adding entry to index file" << std::endl;
m_haystackMapfile.seekp(std::ios::end);
m_haystackMapfile << f;
std::cout << f;
}
不幸的是,我想写入的文件永远不会更新,它的大小始终为 0。也许我搞砸了一些东西,但在谷歌搜索后我找不到答案如何使用 fstream 我可以读取和写入同一个文件...
欢迎任何帮助:)
问候 J.
问题是 seekp()
的错误用法:
- 您在
m_haystackMapfile.seekp(std::ios::end)
中使用一个参数 - 但单一参数仅适用于绝对定位。所以
ios::end
被转换成一个整数,并且会把你定位在一个意想不到的地方(在我的实现中它是 2)。 - 你必须使用
m_haystackMapfile.seekp(0, std::ios::end)
而不是
ios::end
还有另一个问题:您在 std::copy()
中使用的 istream_iterator<>()
将读取流直到它结束。所以 failbit 和 eofbit 将被设置。
因此,在您清除标志之前,任何流操作都不会成功:m_haystackMapfile.clear();
检查 I/O 操作是否成功非常重要。例如,如果seekp
无法定位到想要的位置,它会设置failbit
,然后所有后续写入都会失败。或者,正如@Christophe 指出的那样,如果您将文件读到最后,您将导致 eofbit 被设置。除非清除该位,否则下一个 I/O 操作(甚至 seekp)将失败。
即使 eofbit 已被重置,查找也可能会失败,因为调用应该是 m_haystackMapfile.seekp(0, std::ios::end);
.