如何使open()截断现有文件

时间:2016-06-21 14:10:21

标签: c++ c linux posix

我用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

我错过了什么?

5 个答案:

答案 0 :(得分:5)

请添加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)           将被截断为长度

答案 1 :(得分:3)

问题是O_EXCL标志。来自open(2)的手册页:

  

O_EXCL确保此调用创建文件:如果此标志与O_CREAT一起指定,并且路径名已存在,则open()将失败。

我建议删除O_EXCL,添加O_TRUNC,然后重试。

答案 2 :(得分:2)

open()的手册页说明了O_TRUNC标志:

  

O_TRUNC                 如果文件已经存在并且是常规文件并且开放模式允许写入(即,是O_RDWR或O_WRONLY),则它将被截断为长度0.如果文件是FIFO或终端设备文件,则O_TRUNC标志是                 忽略。否则,O_TRUNC的效果未指定。

答案 3 :(得分:0)

我会告诉你这个错误到底是什么! Open函数将具有返回类型,即在执行此系统调用后将返回一些值(在您的情况下将存储在fd中)。 此值将指示系统调用的执行是否成功。当open系统调用失败时,会自动返回-1(到fd),您已在函数int fd = -1;的第一个语句中初始化了该函数。因此,语句if (fd < 0)正在验证为正确,因此您将收到该错误。 请注意,您不应设置系统调用的返回值,它们将在程序执行时自动返回。您需要做的就是确保捕获该值并对其进行验证。因此,请将函数int fd = -1的第一个语句更改为int fd

底线:您正在将open系统调用的返回值设置为-1,从而告诉编译器其创建应该不惜任何代价失败 !就权限而言,请参考其他评论!! :)

答案 4 :(得分:0)

每个人都说过,这是由于使用了O_EXCL标志,而应该使用O_TRUNC标志。我只是有同样的问题。对于尝试使用这些涉及宏的syscall的人来说,最好的建议是阅读syscall的手册页。在尝试使用宏并使自己困惑之前,请先了解宏的含义。

man 2 open