在Windows中创build一个临时目录?

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

不,没有相当于mkdtemp。 最好的select是使用GetTempPath和GetRandomFileName的组合。

你需要类似这样的代码:

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

我砍了Path.GetTempFileName()给我一个有效的,在磁盘上的伪随机文件path,然后删除该文件,并创build一个具有相同文件path的目录。

这可以避免检查文件path在一段时间或循环中是否可用,根据Chris对Scott Dorman的回答的评论。

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

如果你真的需要一个密码安全的随机名称,你可能想要适应斯科特的答案使用一段时间或做循环,以不断试图创build一个磁盘上的path。

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

一个GUID被devise为具有很高的唯一性概率,而且也不太可能有人手动创build一个与GUIDforms相同的目录(如果他们这样做,那么CreateDirectory()将无法指示它的存在。

GetTempPath是正确的方式; 我不确定你对这种方法的担心是什么。 然后可以使用CreateDirectory来创build它。

这是一个更加暴力的方法来解决临时目录名称的碰撞问题。 这不是一个可靠的方法,但它显着减less了文件夹path碰撞的机会。

人们可能会将其他与进程或程序集有关的信息添加到目录名称中,以使得碰撞更不可能,尽pipe在临时目录名称上显示这样的信息可能是不可取的。 也可以混合时间相关字段的顺序,使文件夹名称看起来更随机。 我个人更喜欢这样做,因为在debugging过程中我更容易find它们。

 string randomlyGeneratedFolderNamePart = Path.GetFileNameWithoutExtension(Path.GetRandomFileName()); string timeRelatedFolderNamePart = DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString() + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString(); string processRelatedFolderNamePart = System.Diagnostics.Process.GetCurrentProcess().Id.ToString(); string temporaryDirectoryName = Path.Combine( Path.GetTempPath() , timeRelatedFolderNamePart + processRelatedFolderNamePart + randomlyGeneratedFolderNamePart); 

@克里斯。 我也迷恋临时目录可能已经存在的远程风险。 关于随机和密码强大的讨论也不完全令我满意。

我的方法build立在一个基本的事实上,即操作系统不能允许两个调用来创build一个文件来成功。 .NETdevise者select隐藏目录的Win32 APIfunction有点令人惊讶,这使得这更容易,因为当你第二次尝试创build一个目录时,它会返回一个错误。 这是我使用的:

  [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); /// <summary> /// Creates the directory if it does not exist. /// </summary> /// <param name="directoryPath">The directory path.</param> /// <returns>Returns false if directory already exists. Exceptions for any other errors</returns> /// <exception cref="System.ComponentModel.Win32Exception"></exception> 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; } 

您可以决定非托pipep / invoke代码的“成本/风险”是否值得。 大多数人会说这不是,但至less现在你有select。

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

如上所述,Path.GetTempPath()是一种方法。 如果用户设置了TEMP环境variables,您也可以调用Environment.GetEnvironmentVariable(“TEMP”) 。

如果您打算使用临时目录作为在应用程序中保存数据的手段,则可能应该将IsolatedStorage用作configuration/状态/等的存储库。

我通常使用这个:

  /// <summary> /// Creates the unique temporary directory. /// </summary> /// <returns> /// Directory path. /// </returns> public string CreateUniqueTempDirectory() { var uniqueTempDir = Path.GetFullPath(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString())); Directory.CreateDirectory(uniqueTempDir); return uniqueTempDir; } 

如果你想确保这个目录名不存在于临时path中,那么你需要检查这个唯一的目录名是否存在,如果它真的存在,就试着创build另一个目录名。

但是这个基于GUID的实现就足够了。 在这种情况下,我没有任何问题的经验。 一些MS应用程序也使用基于GUID的临时目录。