Reputation: 3079
I have small app which at begin will read text file (with serialized objects) in which im storing some obejcts (im doing it by overloading << and >> operators). This text file has to be updated each time new object is created:
fstream m_haystackMapFile;
m_haystackMapfile.open(haystackMapFile, std::ios::binary | std::ios::in | std::ios::out);
first i do read:
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;
}
then after creating new object I do write:
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;
}
unfortunatelly file in which I want to write is never updated and it always has size 0. Maybe im messing up something, but after googling i can't find answer how to using fstream I can read and write to same file...
any help is welcomed :)
regards J.
Upvotes: 1
Views: 2756
Reputation: 241721
It's very important to check success of I/O operations. For example, if seekp
is unable to seek to the desired position, it will set the failbit
, and then all subsequent writes will fail. Or, as @Christophe points out, if you read the file to the end, you will cause the eofbit to be set. Unless that bit is cleared, the next I/O operation (even seekp) will fail.
Even if the eofbit had been reset, the seek probably would fail because the call should have been m_haystackMapfile.seekp(0, std::ios::end);
.
Upvotes: 4
Reputation: 73376
The problem is the wrong usage of seekp()
:
ios::end
in m_haystackMapfile.seekp(std::ios::end)
ios::end
is converted into an integer and will locate you at an unexpected place (on my implementation it's 2). m_haystackMapfile.seekp(0, std::ios::end)
instead There is another problem: the istream_iterator<>()
that you use in your std::copy()
will read the stream until it reaches its end. So the failbit and eofbit will be set.
Connsequently, no stream operation will succed until you clear the flags: m_haystackMapfile.clear();
Upvotes: 3