在Windows中获取临时目录名称的最佳方法是什么?我看到我可以使用GetTempPath
和GetTempFileName
创建一个临时文件,但有没有相当于Linux/BSD mkdtemp
函数来创建一个临时目录?
不,没有相当于mkdtemp.最好的选择是使用GetTempPath和GetRandomFileName的组合.
你需要类似这样的代码:
public string GetTemporaryDirectory() { string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); Directory.CreateDirectory(tempDirectory); return tempDirectory; }
我Path.GetTempFileName()
讨厌在磁盘上给我一个有效的伪随机文件路径,然后删除该文件,并创建一个具有相同文件路径的目录.
根据Chris对Scott Dorman的回答,这可以避免检查文件路径是否在一段时间或循环中可用的需要.
public string GetTemporaryDirectory()
{
string tempFolder = Path.GetTempFileName();
File.Delete(tempFolder);
Directory.CreateDirectory(tempFolder);
return tempFolder;
}
如果您确实需要加密安全的随机名称,您可能需要调整Scott的答案以使用while或do循环来继续尝试在磁盘上创建路径.
我喜欢使用GetTempPath(),像CoCreateGuid()和CreateDirectory()这样的GUID创建函数.
GUID被设计为具有很高的唯一性概率,并且非常不可能有人手动创建具有与GUID相同形式的目录(如果他们这样做,那么CreateDirectory()将失败指示其存在.)
@克里斯。我也很迷恋可能已经存在一个临时目录的远程风险。关于随机性和加密性强的讨论也没有完全使我满意。
我的方法基于这样一个基本事实,即操作系统不允许两个调用创建一个文件才能成功。.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。