如何知道重命名期间哪个文件失败?

时间:2012-02-01 20:27:47

标签: c stdio

我有一个简单的例子:

#include <stdio.h>
#include <errno.h>

int main() {
  int result = rename("filea", "doesntexist/fileb");
  if (result != 0) {
    printf("NOOOO %d\n", errno);
  }
  return 0;
}

我希望区分其中两种可能的失败:

  1. filea不存在
  2. fileb的目录不存在
  3. 但是当它们不存在时它总是返回errno = 2 ...嗯 任何想法我该如何处理?

    由于

    编辑:如果可能,无需手动检查文件是否存在。

    EDIT2:不检查文件是否存在是一个愚蠢的约束;)所以,我已经接受了其中一个答案。谢谢!

4 个答案:

答案 0 :(得分:1)

我不知道如何在不检查文件是否存在的情况下检查文件是否存在,但希望此功能可以帮助您:

#include <sys/stat.h>

if (!fileExists("foo")) { /* foo does not exist */ }

int fileExists (const char *fn)
{
    struct stat buf;
    int i = stat(fn, &buf);
    if (i == 0)
        return 1; /* file found */
    return 0;
}

如果您的目标是保持代码清洁,那么只需使用函数:

int main() 
{
    if (! renameFiles("fileA", "fileB")) { 
        fprintf(stderr, "rename failed...\n"); 
        exit EXIT_FAILURE; 
    }
    return EXIT_SUCCESS;
}

int renameFiles(const char *source, const char *destination)
{
    int result = -1;

    if ( (fileExists(source)) && (!fileExists(destination)) )
        result = rename(source, destination);

    if (result == 0)
        return 1; /* rename succeeded */

    /* 
        Either `source` does not exist, or `destination` 
        already exists, or there is some other error (take 
        a look at `errno` and handle appropriately)
    */

    return 0; 
}

您可以从renameFiles()返回自定义错误代码,并根据哪个文件存在或不存在来有条件地处理错误,或者rename()调用是否存在其他问题。

答案 1 :(得分:1)

首先调用access()(unistd.h)。或stat()。当filea不存在时,您可能会收到ENOENT错误。有些方法可以在fileB上出错:

  1. 无法找到路径
  2. 路径上没有权限
  3. fileB存在且您没有权限
  4. 你的名字太长或格式错误
  5. 还有其他但不常见。

    当fileB不存在时,不会出现错误。您执行mv filea fileb(重命名的内容),mv的所有错误都适用于此处。缺少目标文件不是其中之一。

    你也应该

    #include <errno.h>
    

    因为您引用了errno

答案 2 :(得分:1)

ISO C标准甚至不需要库函数rename在发生错误时设置errno。所有保证的是错误的非零返回值(7.19.4.2,§3)。

因此,这是否可能取决于您的平台(并且它不可移植)。

E.g。在Linux中,只能在errno之后查看rename(根据this man page),无法区分哪些内容丢失了。

答案 3 :(得分:0)

如果你的系统上的errno总是2 ENOENT“没有这样的文件或目录”,你将需要检查是否存在某些东西。在我的系统上,如果 old 不存在或者 new 的目录路径不存在,我会得到2的错误。

然而,还有2个可能的错误。链接http://man.chinaunix.net/unix/susv3/functions/rename.html指定了20个不同的errno值。

我建议如果重命名失败且errno为2,则检查是否存在 old 。如果找到,那么问题是 new 中指定的目录不存在。

相关问题