我有一个FILE* file
包含一些二进制数据的。假设这个数据是一个双精度列表,最后一个条目是一个字符串,描述了这些双精度是什么。我想修改这个字符串(新字符串可能更短)。所以首先我删除旧字符串。我需要找到字符串的起点:
fseek(file,-size(sring.size()),SEEK_END);
然后我该怎么办?我找到了 Delete End of File链接,但我不知道要使用哪一个...一旦文件被重新调整大小,我可以简单地使用写我的新字符串fwrite
吗?
我有一个FILE* file
包含一些二进制数据的。假设这个数据是一个双精度列表,最后一个条目是一个字符串,描述了这些双精度是什么。我想修改这个字符串(新字符串可能更短)。所以首先我删除旧字符串。我需要找到字符串的起点:
fseek(file,-size(sring.size()),SEEK_END);
然后我该怎么办?我找到了 Delete End of File链接,但我不知道要使用哪一个...一旦文件被重新调整大小,我可以简单地使用写我的新字符串fwrite
吗?
iostream 和 iostream都不FILE*
支持截断。如果要编辑文件以使新文件比旧文件短,有两种解决方案:
通常的解决方案是将原始文件复制到一个新文件中,随时进行任何更改。完成后,关闭新文件,确认没有错误(重要一点),然后删除原始文件并重命名为新文件以使用原始名称。如果存在指向原始文件的硬链接,这可能会导致 Unix 系统出现问题。(一般情况下,这不是问题,因为现在大家都在使用软链接。如果是,你应该stat
原件,如果st_nlink
字段大于1,将新文件复制到原件上,然后删除新文件。 ) 另一方面,它是最通用的选项;它适用于文件中任何位置的所有类型的修改。
通常在较低级别有系统特定的功能来截断文件。在 Unix 下,这是ftruncate
. 但是您需要先找到要截断的字节数;ftruncate
需要一个打开的文件,但它不会在文件的当前位置截断。所以你必须 1) 在文件中找到最后一行的开头,2) 寻找它,3) 写入新值,4) 调用ftell
(或者ftello
,如果长度可能太大而无法放入 a long
)找到新的结束位置。此时,您遇到了
FILE*
与较低级别同步的问题;就我个人而言,我要fclose
文件,然后用 重新打开它,然后open
从ftruncate
这个打开的文件描述符上执行。(事实上,就我个人而言,我会使用open
, read
,lseek
, write
,ftruncate
和close
. 或许stat
可以预先找出文件长度。如果您不必翻译双打,那真的没有什么可以FILE*
增加的。
作为一般规则,我会使用第一个解决方案,如果结果太慢,只尝试第二个解决方案。(例如,如果文件包含数十亿个双精度数,复制它们将需要一些时间。)
如果您想调整文件大小,那么ftruncate()
( http://www.linuxmanpages.com/man2/ftruncate.2.php ) 就是您正在寻找的功能。不过,您需要调用结构来获取fileno()
的FILE *
文件描述符ftruncate()
。
至于在文件减小后追加新数据(新字符串),只需寻找到末尾(fseek(file, 0, SEEK_END)
)并fwrite()
在那里 'ing 就可以了。
编辑:fflush()
记得在截断文件之前打电话!