我正在使用 C 将一些数据写入文件。我想删除文件中以前写入的文本,以防它比我现在写的内容长。 我想减小文件的大小或截断直到最后。我怎样才能做到这一点?
如果您想将文件的先前内容保留到一定长度(大于零的长度,其他答案提供了),那么 POSIX 提供了
truncate()
和 ftruncate()
函数来完成这项工作。
#include <unistd.h>
int ftruncate(int fildes, off_t length);
int truncate(const char *path, off_t length);
名称表明了主要目的 - 缩短文件。 但是,如果指定的长度比先前的长度长,则文件将增长(零填充)到新的大小。 请注意,
ftruncate()
适用于文件描述符,而不是 FILE *
;你可以使用:
if (ftruncate(fileno(fp), new_length) != 0) ...error handling...
但是,您应该意识到,混合文件流 (
FILE *
) 和文件描述符 (int
) 访问单个文件很容易导致混乱 - 请参阅某些问题的评论。 这应该是最后的手段。
不过,出于您的目的,打开时截断可能就是您所需要的,为此,其他人提供的选项就足够了。
SetEndOfFile()
和一个相关函数 SetFileValidData()
函数可以完成类似的工作,但使用不同的界面。 基本上,您寻找要设置文件结尾的位置,然后调用该函数。
还有一个函数
_chsize()
,如 sofr 的 answer 中所述。
在 Windows 系统中没有标头
<unistd.h>
但您可以使用 截断文件
FILE *f = ...;
_chsize( fileno(f), size);
这是操作系统的功能。标准 POSIX 方法是:
open("file", O_TRUNC | O_WRONLY);
如果要在某种风格的 UNIX 下运行,这些 API 应该可用:
#include <unistd.h>
#include <sys/types.h>
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);
根据我的 Linux 机器上的“man truncate”,这些是符合 POSIX 标准的。 请注意,如果您传递的长度大于当前长度,这些调用实际上会增加文件的大小(!)。
啊,你编辑了你的帖子,你正在使用C。当你打开文件时,用“w+”模式打开它,就像这样,它会截断它以准备写入:
FILE* f = fopen("C:\\gabehabe.txt", "w+");
fclose(file);
要在 C++ 中截断文件,您可以简单地为该文件创建一个 ofstream 对象,使用 ios_base::trunc 作为文件模式来截断它,如下所示:
ofstream x("C:\\gabehabe.txt", ios_base::trunc);
如果您想截断整个文件,打开文件进行写入即可完成此操作。 否则,你必须打开文件进行读取,并将文件中你想要保留的部分读取到临时变量中,然后将其输出到你需要的任何地方。
截断整个文件:
FILE *file = fopen("filename.txt", "w"); //automatically clears the entire file for you.
截断部分文件:
FILE *inFile = fopen("filename.txt", "r");
//read in the data you want to keep
fclose(inFile);
FILE *outFile = fopen("filename.txt", "w");
//output back the data you want to keep into the file, or what you want to output.
fclose(outFile);
在 Windows 中,如果您只想在完成写入后截断文件,那么
SetEndOfFile()
就是 HANDLE
的方法。如果您正在使用 fd
,那么 SetEndOfFile((HANDLE) _get_osfhandle(fd))
。 _chsize()
或 _ftruncate()
可能仅支持 32 位编译器上的 32 位参数。据我所知,在 Unix 中没有像 SetEndOfFile()
这样的“无大小”功能。