【问题标题】:How to make open() truncate an existing file如何使 open() 截断现有文件
【发布时间】:2016-06-21 14:10:20
【问题描述】:

我正在使用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

我错过了什么?

【问题讨论】:

  • 您要删除还是截断文件
  • 您是否尝试过添加 O_TRUNC 标志。
  • @sas 水,目标是打开一个新的空文件。我不想得到这个错误
  • 添加O_TRUNC 并删除O_EXCLO_EXCL 表示该文件可能不存在 - 如果存在,open() 将失败。 O_TRUNC 表示如果文件已存在则截断该文件。

标签: c++ c linux posix


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 这是其中的一部分——但只是其中的一部分。您也必须删除O_EXCL,因为如果它存在,则系统调用将无法打开该文件,如果它已经存在,则在截断有机会发生之前。请注意,如果可能的话,最好提供您查阅的手册页的在线版本的链接。对于 Linux,您通常可以使用 linux.die.net 作为手册页的来源——尽管有很多替代方案。
      【解决方案4】:

      正如大家所说,这是由于使用了O_EXCL 标志,而应该是O_TRUNC 标志。我刚遇到同样的问题。对于尝试使用这些涉及宏的系统调用的人,我最好的建议是阅读系统调用的手册页。在尝试使用宏并让自己感到困惑之前,请先了解宏的含义。

      man 2 open

      【讨论】:

        【解决方案5】:

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

        底线:您将open 系统调用的返回值设置为-1,从而告诉编译器它的创建应该不惜一切代价失败!至于权限,请参考其他cmets!! :)

        【讨论】:

        • int fd = -1 不设置 open 调用的返回值。调用open之前不需要设置这个变量,但是没有任何作用。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-01
        • 2019-07-04
        • 2010-10-26
        • 2011-09-26
        • 2011-12-04
        • 1970-01-01
        相关资源
        最近更新 更多