【问题标题】:How to create a temporary directory in C in Linux?如何在 C 中创建一个临时目录?
【发布时间】:2013-09-18 12:08:22
【问题描述】:

我正在尝试创建一个临时目录以在其中执行一些操作,然后在最后删除整个内容。我在 UNIX 系统中使用 C 语言,所以我希望对这个环境有一些顺应性。

最好的编程方法是什么?

编辑 我真的需要一个目录,而不仅仅是一个文件。小程序是想试试我能不能执行一个项目的svn checkout。因此,它应该能够创建完整的文件和目录层次结构。

【问题讨论】:

    标签: c unix glibc


    【解决方案1】:

    你应该使用mkdtemp函数。

    #define  _POSIX_C_SOURCE 200809L
    
    #include <stdlib.h>
    #include <unistd.h>
    #include <stdio.h>
    
    int main()
    {
            char template[] = "/tmp/tmpdir.XXXXXX";
            char *dir_name = mkdtemp(template);
    
            if(dir_name == NULL)
            {
                    perror("mkdtemp failed: ");
                    return 0;
            }
    
            /* Use it here */
            printf("%s", dir_name);
    
    
    
            /* Don't forget to delete the folder afterwards. */
            if(rmdir(dir_name) == -1)
            {
                    perror("rmdir failed: ");
                    return 0;
            }
    
    
            return 0;
    
    }
    

    之后别忘了删除目录!

    【讨论】:

    • 事实上,我很难让它发挥作用。而且,看不到任何例子。所以,我决定在这里发布我的解决方案以帮助其他人。
    • 干得好,我 +1!
    • @perror 在没有它的情况下它可以正常工作。 gcc 4.7.3 和 gcc 4.8。
    • @perror,是的,你是对的。我将编辑我的答案,并在这里给出完整的代码。
    • 一个问题是这个函数如果不是像tmpnam这样的ANSI C。
    【解决方案2】:

    我建议将 mkdtemp() 函数与 C API (glibc) 中的常用函数一起使用。这是一个完整的答案:

    编辑:很遗憾,answer from Nemanja Boric 在实践中不可用,因为rmdir() 函数仅用于删除空目录。这是一个完整的正确答案:

    #define  _POSIX_C_SOURCE 200809L
    #define  _XOPEN_SOURCE 500L
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    #include <errno.h>
    #include <ftw.h>
    
    /* Call-back to the 'remove()' function called by nftw() */
    static int
    remove_callback(const char *pathname,
                    __attribute__((unused)) const struct stat *sbuf,
                    __attribute__((unused)) int type,
                    __attribute__((unused)) struct FTW *ftwb)
    {
      return remove (pathname);
    }
    
    int
    main ()
    {
      /* Create the temporary directory */
      char template[] = "/tmp/tmpdir.XXXXXX";
      char *tmp_dirname = mkdtemp (template);
    
      if (tmp_dirname == NULL)
      {
         perror ("tempdir: error: Could not create tmp directory");
         exit (EXIT_FAILURE);
      }
    
      /* Change directory */
      if (chdir (tmp_dirname) == -1)
      {
         perror ("tempdir: error: ");
         exit (EXIT_FAILURE);
      }
    
      /******************************/
      /***** Do your stuff here *****/
      /******************************/
    
      /* Delete the temporary directory */
      if (nftw (tmp_dirname, remove_callback, FOPEN_MAX,
                FTW_DEPTH | FTW_MOUNT | FTW_PHYS) == -1)
        {
          perror("tempdir: error: ");
          exit(EXIT_FAILURE);
        }
    
      return EXIT_SUCCESS;
    }
    

    【讨论】:

    • 您应该始终检查系统调用的返回值。
    • 如果/tmp 不存在或无法使用怎么办?
    • @TimSchaeffer 这就是为什么我说 perror 应该检查 mkdtemp 的返回值是否为 NULL。
    • 使用system(rm -rf tmp) 是a) 慢,b) 在任何意义上都不安全 c) 它会破坏你的信号 d) 不便携,...你真的应该使用(n)ftw/remove 或@ 987654330@/readdir/rmdir/unlink 删除您的 tmp 目录。
    • 您应该更改template 变量的名称,因为它是C++ 中的保留关键字。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    • 2010-09-21
    • 1970-01-01
    相关资源
    最近更新 更多