如何使 open() 截断现有文件
How to make open() truncate an existing file
我正在用 open()
函数打开一个文件。
我希望 open()
函数丢弃文件内容(如果它已经存在),然后将文件视为新的空文件。
我尝试使用以下代码:
int open_file(char *filename)
{
int fd = -1;
fd = open(filename, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
if (fd < 0) {
printf("Couldn't create new file %s: %s\n",
filename, strerror(errno));
return -1;
}
close(fd);
return 0;
}
但我收到以下错误:
Couldn't create new file kallel333: File exists
我错过了什么?
open()
的手册页是这样描述 O_TRUNC 标志的:
O_TRUNC
If the file already exists and is a regular file and the open mode allows writing (i.e., is O_RDWR or O_WRONLY) it will be truncated to length 0. If the file is a FIFO or terminal device file, the O_TRUNC flag is
ignored. Otherwise the effect of O_TRUNC is unspecified.
请添加 O_TRUNC 标记并删除 O_EXCL。
open(filename, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
来自打开的手册页 -
O_EXCL 确保此调用创建文件:如果此标志是
与 O_CREAT 一起指定,并且路径名已经
存在,则 open() 将失败。
O_TRUNC
如果文件已经存在并且是一个普通文件并且
访问模式允许写入(即 O_RDWR 或 O_WRONLY)它
将被截断到长度
问题是 O_EXCL
标志。来自 open(2)
的手册页:
O_EXCL Ensure that this call creates the file: if this flag is specified in conjunction with O_CREAT, and pathname already exists, then open() will fail.
我建议删除 O_EXCL
,添加 O_TRUNC
,然后重试。
我会告诉你这个错误是怎么回事! Open
函数将具有 return 类型,即在执行此系统调用后某些值将被 returned(在您的情况下将存储在 fd
中)。 该值将指示系统调用的执行是否成功。当 open
系统调用失败时,它 自动 returns -1 (to fd) 您已经在函数的第一条语句中初始化 int fd = -1;
.因此,语句 if (fd < 0)
被验证为正确,因此您会收到该错误。 请注意,您不应设置系统调用的 return 值,它们将在程序执行时自动 returned。您需要做的只是确保捕获该值并验证它。 因此,请将函数 int fd = -1
的第一条语句更改为简单的 int fd
。
底线:您正在将 open
系统调用的 return 值设置为 -1,从而 告诉编译器它的创建无论如何都会失败 !!至于权限,请参考其他评论! :)
正如大家所说,这是由于使用了 O_EXCL
标志,而应该是 O_TRUNC
标志。我刚刚遇到了同样的问题。对于任何尝试使用这些涉及宏的系统调用的人,我最好的建议是阅读系统调用的手册页。在您尝试使用它们并混淆自己之前,请先了解您的宏的含义。
man 2 open
我正在用 open()
函数打开一个文件。
我希望 open()
函数丢弃文件内容(如果它已经存在),然后将文件视为新的空文件。
我尝试使用以下代码:
int open_file(char *filename)
{
int fd = -1;
fd = open(filename, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
if (fd < 0) {
printf("Couldn't create new file %s: %s\n",
filename, strerror(errno));
return -1;
}
close(fd);
return 0;
}
但我收到以下错误:
Couldn't create new file kallel333: File exists
我错过了什么?
open()
的手册页是这样描述 O_TRUNC 标志的:
O_TRUNC If the file already exists and is a regular file and the open mode allows writing (i.e., is O_RDWR or O_WRONLY) it will be truncated to length 0. If the file is a FIFO or terminal device file, the O_TRUNC flag is ignored. Otherwise the effect of O_TRUNC is unspecified.
请添加 O_TRUNC 标记并删除 O_EXCL。
open(filename, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
来自打开的手册页 -
O_EXCL 确保此调用创建文件:如果此标志是 与 O_CREAT 一起指定,并且路径名已经 存在,则 open() 将失败。
O_TRUNC 如果文件已经存在并且是一个普通文件并且 访问模式允许写入(即 O_RDWR 或 O_WRONLY)它 将被截断到长度
问题是 O_EXCL
标志。来自 open(2)
的手册页:
O_EXCL Ensure that this call creates the file: if this flag is specified in conjunction with O_CREAT, and pathname already exists, then open() will fail.
我建议删除 O_EXCL
,添加 O_TRUNC
,然后重试。
我会告诉你这个错误是怎么回事! Open
函数将具有 return 类型,即在执行此系统调用后某些值将被 returned(在您的情况下将存储在 fd
中)。 该值将指示系统调用的执行是否成功。当 open
系统调用失败时,它 自动 returns -1 (to fd) 您已经在函数的第一条语句中初始化 int fd = -1;
.因此,语句 if (fd < 0)
被验证为正确,因此您会收到该错误。 请注意,您不应设置系统调用的 return 值,它们将在程序执行时自动 returned。您需要做的只是确保捕获该值并验证它。 因此,请将函数 int fd = -1
的第一条语句更改为简单的 int fd
。
底线:您正在将 open
系统调用的 return 值设置为 -1,从而 告诉编译器它的创建无论如何都会失败 !!至于权限,请参考其他评论! :)
正如大家所说,这是由于使用了 O_EXCL
标志,而应该是 O_TRUNC
标志。我刚刚遇到了同样的问题。对于任何尝试使用这些涉及宏的系统调用的人,我最好的建议是阅读系统调用的手册页。在您尝试使用它们并混淆自己之前,请先了解您的宏的含义。
man 2 open