仅重写文件的第一个字节

时间:2013-08-16 15:30:27

标签: c file file-io rewrite stdio

我在重写第一个2.5KB的文件时遇到小问题。我的代码应该读取2KB和512字节到动态分配的内存,然后重写更大文件的特定字节。

f = fopen(argv[2], "rb");
if(f==NULL)
    printf("File doesn't exist!");
fseek(f, 0, SEEK_SET);
data = calloc(2*1024+512, 1);
fread(data, 1, 2*1024+512, f);
fclose(f);

f = fopen(argv[1], "ab");
if(f==NULL)
    printf("File doesn't exist!");
fseek(f, 0, SEEK_SET);
fwrite(data, 1, 446, f);
fseek(f, 512, SEEK_SET);
fwrite(((char*)data)+512, 1, 2*1024, f);
fclose(f);

当我尝试使用wb模式时,它会删除第二个文件的内容。当我使用ab模式并寻找文件的开头时,会在前面附加以前的内容。

有没有办法(使用标准C库)重写文件内容而不附加和复制写入文件的剩余内容?请帮忙。

2 个答案:

答案 0 :(得分:3)

你想要ab++表示更新模式。如果该文件存在,则只会打开它并且内容不会更改。 wb本身只会删除原始文件并创建一个新文件。

答案 1 :(得分:2)

"rb"模式打开位于开头的文件;最初的fseek()是多余的。

第二次打开"ab"打开文件,以便以附加模式书写。无论您事先执行fseek()次操作,所有写操作都将发生在文件末尾。

您可以合理地使用模式"rb+"打开文件一次以进行读写:

if ((f = fopen(argv[2], "rb+")) != 0)
{
    char *data = calloc(2*1024+512, 1);   // Missing error check
    fread(data, 1, 2*1024+512, f);        // Missing error check
    // Modify data?
    fseek(f, 0, SEEK_SET);
    fwrite(data, 1, 446, f);
    fseek(f, 512, SEEK_SET);
    fwrite(((char*)data)+512, 1, 2*1024, f);
    fclose(f);
}

在使用calloc()之前,代码应检查data是否成功;它还应该错误检查fread()以确保它获得了预期的数据。据推测,中间的某些东西会修改从文件中读取的数据。


ISO / IEC 9899:2011(当前的C标准)对fopen()的模式有所说明 - 除了x标志之外,之前的标准大致相同,这是新的在C11:

  

§7.21.5.3fopen函数

     

¶3参数mode指向一个字符串。如果字符串是以下之一,则文件以指示的模式打开。否则,行为是未定义的。 271)

     
      
  • r打开文本文件进行阅读
  •   
  • w截断为零长度或创建用于编写的文本文件
  •   
  • wx创建用于编写的文本文件
  •   
  • a追加;打开或创建文本文件,以便在文件结尾处写入
  •   
  • rb打开二进制文件进行阅读
  •   
  • wb截断为零长度或创建用于写入的二进制文件
  •   
  • wbx创建用于编写的二进制文件
  •   
  • ab追加;打开或创建二进制文件以便在文件结尾处写入
  •   
  • r+打开文本文件进行更新(读写)
  •   
  • w+截断为零长度或创建文本文件以进行更新
  •   
  • w+x创建用于更新的文本文件
  •   
  • a+追加;打开或创建文本文件以进行更新,在文件结尾处写入
  •   
  • r+brb+打开二进制文件进行更新(读写)
  •   
  • w+bwb+截断为零长度或创建二进制文件以进行更新
  •   
  • w+bxwb+x创建二进制文件以进行更新
  •   
  • a+bab+追加;打开或创建二进制文件以进行更新,在文件结尾处写入
  •   
     

271)如果字符串以上述序列之一开头,则实现可能会选择忽略   剩下的字符,或者它可能会用它们来选择不同类型的文件(其中一些可能不是   符合§7.21.2)中的属性。