不能在文件的特定位置上覆盖.覆盖特定位置上的内容将删除其之前的所有内容,并将其后的值移动 [英] Can't Over write on a specific location on a file. Over write on a specific location deletes all the contents before it and moves the value after it
问题描述
在我的项目中,需要读取和写入二进制文件,基本上是将文件中的链表序列化,在其中以二进制格式存储值并记住tellp()/tellg()偏移量,但是,我不能这样做.这样会将其中的所有内容都擦除为零,而不是将其插入将当前内容推回原位.
In my project, there is a need to read and write to binary file, basically serializing linked lists in a file, where I store the value in binary format and remember the tellp()/tellg() offset, how ever, I cannot do that. That erases all the contents in it to zero and instead of inserting it pushes the current content back.
例如,在下面的程序中,我打开一个文件,写入值1,120,323.然后将其关闭并读取,它会显示确切的正确值1,120,323.但是,当我尝试替换值120-> 220时,1变为零,并且该值读取为0 220220.基本上,220会覆盖并推回323.
For Example, in the below program, I open a file, write values say 1,120,323. Then close it and read it, it shows the exact correct values 1,120,323. But When I try to replace the value of 120->220, 1 becomes zero and the value read as 0 220 220. Basically 220 over writes and pushes 323 back.
#include <iostream>
#include <fstream>
#include <cstdlib>
int main() {
std::cout<<"File Ofstream Testing "<<std::endl;
const char * file_name = "Test_File.bin";
int ONE = 1;
int ZERO = 0;
int ONE_TWENTY = 120;
int TWO_TWENTY = 220;
int THREE_TWENTY_THREE = 323;
int THREE_FORTY_FIVE = 345;
//---------------------------------------------------------------------------
{
std::ofstream file_write(file_name, std::ios::out|std::ios::binary);
if(!(file_write.is_open())) {
std::cout<<"File cannot be opened "<<std::endl;
exit(0);
}
file_write.seekp(0);
file_write.write((char *)&ONE,sizeof(int));
file_write.write((char *)&ONE_TWENTY,sizeof(int));
file_write.write((char *)&THREE_TWENTY_THREE,sizeof(int));
file_write.close();
}
//---------------------------------------------------------------------------
{
std::ifstream file_read(file_name,std::ios::in|std::ios::binary);
if(!(file_read.is_open())) {
std::cout<<"File cannot be opened "<<std::endl;
exit(0);
}
int temp;
file_read.seekg(0);
file_read.read((char *)&temp,sizeof(int));
std::cout<<"Temp "<<temp<<std::endl;
file_read.read((char *)&temp,sizeof(int));
std::cout<<"Temp "<<temp<<std::endl;
file_read.read((char *)&temp,sizeof(int));
std::cout<<"Temp "<<temp<<std::endl;
file_read.close();
}
//---------------------------------------------------------------------------
{
std::ofstream file_write(file_name, std::ios::out|std::ios::binary);
if(!(file_write.is_open())) {
std::cout<<"File cannot be opened "<<std::endl;
exit(0);
}
file_write.seekp(sizeof(int));
file_write.write((char *)&TWO_TWENTY,sizeof(int));
file_write.seekp(sizeof(int) + sizeof(int));
file_write.write((char *)&THREE_FORTY_FIVE,sizeof(int));
file_write.close();
}
//--------------------------------------------------------------------------
{
std::ifstream file_read(file_name,std::ios::in|std::ios::binary);
if(!(file_read.is_open())) {
std::cout<<"File cannot be opened "<<std::endl;
exit(0);
}
int temp;
file_read.seekg(0);
file_read.read((char *)&temp,sizeof(int));
std::cout<<"Temp "<<temp<<std::endl;
file_read.seekg(sizeof(int));
file_read.read((char *)&temp,sizeof(int));
std::cout<<"Temp "<<temp<<std::endl;
file_read.seekg(sizeof(int) + sizeof(int));
file_read.read((char *)&temp,sizeof(int));
std::cout<<"Temp "<<temp<<std::endl;
file_read.close();
}
//--------------------------------------------------------------------------------
return 0;
}//fn:main
推荐答案
对于输出流,用std::ios::out
打开等同于std::ios::out | std::ios::trunc
,因此当您第二次声明std::ofstream file_write
时,先前编写的内容将得到丢弃,您将重新写入文件.然后在空流上执行file_write.seekp(sizeof(int));
时,将写入零字节.
如果需要附加到ofstream
,则可以使用std::ios:app
打开它.那不会截断文件,但另一方面,它只能让您追加到文件中.
For output streams, opening with std::ios::out
is equivalent to std::ios::out | std::ios::trunc
, so when you declare std::ofstream file_write
for the second time, the previously written content gets discarded and you're writing the file anew. When you then do file_write.seekp(sizeof(int));
on an empty stream, zero bytes are written.
If you needed to append to an ofstream
then you would open it with std::ios:app
. That wouldn't truncate the file, but it would only let you append to it on the other hand.
如果要对文件流进行随机访问写入,则需要将其声明为fstream
并以读写模式打开.因此,您需要的是:
If you want to do random-access writing on an file stream, you need to declare it as fstream
and open it in both reading and writing mode. So what you need is:
std::fstream file_write(file_name, std::ios::in | std::ios::out | std::ios::binary);
这篇关于不能在文件的特定位置上覆盖.覆盖特定位置上的内容将删除其之前的所有内容,并将其后的值移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!