C语言 用于生成具有漂亮文件名的临时文件的 POSIX 方法



我想生成一个带有"漂亮"名称的临时文件,例如

my-app-Mar27-120357-Qf3K0a.html

同时遵循安全性的最佳实践。

POSIX 为我提供了mkstemp(3)它需要一个文件名模板(通常类似于 /tmp/my-app-XXXXXX(,但它有两个问题:

  1. 我需要自己选择输出目录。当我看到 glibc tempnam(3)(出于安全原因已弃用(考虑许多因素时,我希望让库函数选择它。
  2. 文件名中没有扩展名

第二项可以通过mkstemps(3)来解决,它需要许多字符来保留为用户定义的扩展名。 就我而言,我可以通过my-app-Mar27-120357-XXXXXX.html5但它有自己的问题:

  1. 我仍然需要选择输出目录
  2. 它不是完全便携的。NetBSD似乎缺乏它。

所以我正在考虑使用已弃用的tempnam(3)生成带有输出目录路径的文件名,用 X 覆盖文件名部分并将其提供给mkstemp(3),然后将文件重命名为我的首选格式。所以问题出在最后一步,重命名而不覆盖;在POSIX中可能吗?

或者有更好的选择吗?

mkstemp以它想要的符合 POSIX 的方式制作它想要的文件。使用 symlink 从您选择的源文件和路径到与使用 mkstemp 的任何内容匹配的目标的符号链接。完成后删除符号链接。

另一种方法是简单地修改模板并添加路径。我们在这里的 BEDOPS 工具包中描述了这样一个功能,sort-bed应用程序使用它来允许最终用户指定临时中间文件的存储位置:https://github.com/bedops/bedops/blob/6da835468565dfc30a3fcb65807e91fcf133ea2b/applications/bed/sort-bed/src/SortDetails.cpp#L115

FILE *
createTmpFile(char const* path, char** fileName)
{
    FILE* fp;
    int fd;
    char* tmpl;
    if (path == NULL)
        {
            fileName = NULL;
            return tmpfile();
        }
    tmpl = static_cast<char*>( malloc(1 + strlen(path) + L_tmpnam) );
    strcpy(tmpl, path);
    strcpy(tmpl+strlen(path), "/sb.XXXXXX");
    fd = mkstemp(tmpl);
    if(fd == -1)
        {
            fprintf(stderr, "unable to create temp file!n");
            return NULL;
        }
    fp = fdopen(fd, "wb+");
    *fileName = static_cast<char*>( malloc(strlen(tmpl) + 1) );
    strcpy(*fileName, tmpl);
    free(tmpl);
    return fp;
} 

这将使用 L_tmpnam 宏(stdio库的一部分(来设置变量tmpl(最终文件名(可以存储的字符数。

这在Linux和OS X(BSD(主机下编译和工作,并且还使用POSIX例程。

它比我的其他解决方案更复杂,但它可能更适合您的用例。

最新更新