不能在文件的特定位置上覆盖.覆盖特定位置上的内容将删除其之前的所有内容,并将其后的值移动 [英] 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

查看:71
本文介绍了不能在文件的特定位置上覆盖.覆盖特定位置上的内容将删除其之前的所有内容,并将其后的值移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的项目中,需要读取和写入二进制文件,基本上是将文件中的链表序列化,在其中以二进制格式存储值并记住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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆