当前位置:  开发笔记 > 编程语言 > 正文

在Windows中创建临时目录?

如何解决《在Windows中创建临时目录?》经验,为你挑选了4个好方法。

在Windows中获取临时目录名称的最佳方法是什么?我看到我可以使用GetTempPathGetTempFileName创建一个临时文件,但有没有相当于Linux/BSD mkdtemp函数来创建一个临时目录?



1> Scott Dorman..:

不,没有相当于mkdtemp.最好的选择是使用GetTempPath和GetRandomFileName的组合.

你需要类似这样的代码:

public string GetTemporaryDirectory()
{
   string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
   Directory.CreateDirectory(tempDirectory);
   return tempDirectory;
}


@Chris:GetRandomFileName方法返回一个加密强大的随机字符串,可用作文件夹名称或文件名.我认为理论上可能的结果路径已经存在,但没有其他方法可以做到这一点.您可以检查路径是否存在,以及它是否再次调用Path.GetRandomFileName()并重复.
在您检查目录不存在之后,上帝可以暂停宇宙,潜入并使用您即将编写的所有相同文件创建相同的目录,从而导致您的应用程序爆炸,只是毁了您的一天.
GetRandomFileName生成11个随机小写字母和数字,表示域大小为(26 + 10)^ 11 = ~57位.您可以随时拨打两个电话来对齐它
@Chris:是的,如果你担心这种程度的安全性,那么另一个进程可能会创建Path.Combine和Directory.CreateDirectory调用之间的目录.
这似乎有点危险.特别是,Path.Combine(Path.GetTempPath(),Path.GetRandomFileName())将返回已存在的目录的名称(小,但非零,对吧?).如果tempDirectory已经存在,则Directory.CreateDirectory(tempDirectory)不会抛出异常,因此应用程序将不会检测到这种情况.然后你可能有两个应用程序踩到彼此的工作.在.NET中有更安全的替代方案吗?

2> Steve Jansen..:

Path.GetTempFileName()讨厌在磁盘上给我一个有效的伪随机文件路径,然后删除该文件,并创建一个具有相同文件路径的目录.

根据Chris对Scott Dorman的回答,这可以避免检查文件路径是否在一段时间或循环中可用的需要.

public string GetTemporaryDirectory()
{
  string tempFolder = Path.GetTempFileName();
  File.Delete(tempFolder);
  Directory.CreateDirectory(tempFolder);

  return tempFolder;
}

如果您确实需要加密安全的随机名称,您可能需要调整Scott的答案以使用while或do循环来继续尝试在磁盘上创建路径.



3> 小智..:

我喜欢使用GetTempPath(),像CoCreateGuid()和CreateDirectory()这样的GUID创建函数.

GUID被设计为具有很高的唯一性概率,并且非常不可能有人手动创建具有与GUID相同形式的目录(如果他们这样做,那么CreateDirectory()将失败指示其存在.)



4> Andrew Denni..:

@克里斯。我也很迷恋可能已经存在一个临时目录的远程风险。关于随机性和加密性强的讨论也没有完全使我满意。

我的方法基于这样一个基本事实,即操作系统不允许两个调用创建一个文件才能成功。.NET设计人员选择隐藏目录的Win32 API功能,这有点让人惊讶,这使此操作更加容易,因为当您尝试第二次创建目录时,它确实返回错误。这是我使用的:

    [DllImport(@"kernel32.dll", EntryPoint = "CreateDirectory", SetLastError = true, CharSet = CharSet.Unicode)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool CreateDirectoryApi
        ([MarshalAs(UnmanagedType.LPTStr)] string lpPathName, IntPtr lpSecurityAttributes);

    /// 
    /// Creates the directory if it does not exist.
    /// 
    /// The directory path.
    /// Returns false if directory already exists. Exceptions for any other errors
    /// 
    internal static bool CreateDirectoryIfItDoesNotExist([NotNull] string directoryPath)
    {
        if (directoryPath == null) throw new ArgumentNullException("directoryPath");

        // First ensure parent exists, since the WIN Api does not
        CreateParentFolder(directoryPath);

        if (!CreateDirectoryApi(directoryPath, lpSecurityAttributes: IntPtr.Zero))
        {
            Win32Exception lastException = new Win32Exception();

            const int ERROR_ALREADY_EXISTS = 183;
            if (lastException.NativeErrorCode == ERROR_ALREADY_EXISTS) return false;

            throw new System.IO.IOException(
                "An exception occurred while creating directory'" + directoryPath + "'".NewLine() + lastException);
        }

        return true;
    }

您可以确定非托管p /调用代码的“成本/风险”是否值得。大多数人会说不是,但是至少您现在可以选择。

CreateParentFolder()作为练习留给学生。我使用Directory.CreateDirectory()。小心获取目录的父目录,因为在根目录时该目录为null。

推荐阅读
可爱的天使keven_464
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有