如何在Linux中使用C语言创建临时目录?

14

我正在尝试创建一个临时目录,在其中执行一些操作,然后在最后删除整个目录。我在UNIX系统中使用C语言,因此希望能够与该环境兼容。

编写这个程序的最佳方法是什么?

编辑 我确实需要一个目录,不仅仅是一个文件。 这个小程序旨在尝试是否可以执行项目的svn checkout。 因此,它应该能够创建完整的文件和目录层次结构。

2个回答

11
您应该使用 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;

}

不要忘记之后删除该目录!


2
事实上,我曾经花费了很多时间才让它正常工作。而且,没有任何示例可供参考。因此,我决定在这里发布我的解决方案,以帮助其他人。 - perror
干得好,我给你点赞! - Nemanja Boric
@perror 在这里没有问题,不需要它。gcc 4.7.3和gcc 4.8。 - Nemanja Boric
@perror,是的,你说得对。我会编辑我的答案并在这里提供整个代码。 - Nemanja Boric
1
一个问题是这个函数不像 tmpnam 那样符合 ANSI C。 - Ciro Santilli OurBigBook.com
显示剩余3条评论

6
我建议使用C API(glibc)中的常规函数,将mkdtemp()函数与之组合使用。以下是完整的答案:

编辑:来自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;
}

1
你应该始终检查系统调用的返回值。 - Nemanja Boric
如果/tmp不存在或无法使用怎么办? - Tim Schaeffer
@TimSchaeffer 这就是为什么我说perror应该检查mkdtemp的返回值是否为NULL。 - Nemanja Boric
7
使用system(rm -rf tmp)有以下问题:a) 速度慢,b) 完全不安全,c) 可能会破坏信号,d) 不可移植。您应该使用(n)ftw/removeopendir/readdir/rmdir/unlink来删除您的tmp目录。 - Nemanja Boric
7
你应该更改template变量的名称,因为它是C++中的保留关键字。 - SukkoPera

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接