当前位置:  开发笔记 > 后端 > 正文

创建临时文件夹

如何解决《创建临时文件夹》经验,为你挑选了5个好方法。

我正在开发一个需要为应用程序创建多个临时文件夹的程序.这些将不会被用户看到.该应用程序是用VB.net编写的.我可以想到几个方法来做它,如增量文件夹名称或随机编号的文件夹名称,但我想知道,其他人如何解决这个问题?



1> Rick..:

更新:添加了File.Exists检查每条评论(2012年6月19日)

这是我在VB.NET中使用的内容.基本上与呈现的相同,除了我通常不想立即创建文件夹.

使用GetRandomFilename的优点是它不会创建文件,因此如果您使用名称而不是文件,则不必清理.就像使用文件夹名称一样.

Private Function GetTempFolder() As String
    Dim folder As String = Path.Combine(Path.GetTempPath, Path.GetRandomFileName)
    Do While Directory.Exists(folder) or File.Exists(folder)
        folder = Path.Combine(Path.GetTempPath, Path.GetRandomFileName)
    Loop

    Return folder
End Function

随机文件名示例:

C:\ Documents and Settings\username\Local Settings\Temp\u3z5e0co.tvq


这是使用Guid获取临时文件夹名称的变体.

Private Function GetTempFolderGuid() As String
    Dim folder As String = Path.Combine(Path.GetTempPath, Guid.NewGuid.ToString)
    Do While Directory.Exists(folder) or File.Exists(folder)
        folder = Path.Combine(Path.GetTempPath, Guid.NewGuid.ToString)
    Loop

    Return folder
End Function

guid示例:

C:\ Documents and Settings\username\Local Settings\Temp\2dbc6db7-2d45-4b75-b27f-0bd492c60496



2> juan..:

你必须使用 System.IO.Path.GetTempFileName()

在磁盘上创建唯一命名的零字节临时文件,并返回该文件的完整路径.

您可以使用System.IO.Path.GetDirectoryName(System.IO.Path.GetTempFileName())仅获取临时文件夹信息,并在其中创建文件夹

它们是在windows temp文件夹中创建的,这是最佳实践



3> urini..:

只是为了澄清:

System.IO.Path.GetTempPath()

只返回临时文件夹的文件夹路径.

System.IO.Path.GetTempFileName()

返回完全限定的文件名(包括路径),这样:

System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetTempFileName())

是多余的.


GetTempPath和GetTempFileName是两种完全不同的方法.GetTempPath只返回系统临时文件夹的位置,而GetTempFileName创建一个临时零长度文件并返回该文件的完整路径.

4> Jonathan Wri..:

在以下情况下可能存在竞争条件:

创建一个临时文件GetTempFileName(),删除它,并创建一个具有相同名称的文件夹,或

使用GetRandomFileName()Guid.NewGuid.ToString命名文件夹并稍后创建文件夹

GetTempFileName()发生删除之后,另一个应用程序可以成功创建具有相同名称的临时文件.在CreateDirectory()随后会失败.

同样,在调用GetRandomFileName()和创建目录之间,另一个进程可能会创建一个具有相同名称的文件或目录,从而再次导致CreateDirectory()失败.

对于大多数应用程序,临时目录由于竞争条件而失败是可以的.毕竟这是非常罕见的.对他们来说,这些比赛经常被忽略.

在Unix shell脚本世界中,以安全的无竞争方式创建临时文件和目录是一件大事.许多机器具有多个(恶意)用户 - 认为共享Web主机 - 并且许多脚本和应用程序需要在shared/tmp目录中安全地创建临时文件和目录.有关如何从shell脚本安全地创建临时目录的讨论,请参阅在Shell脚本中安全地创建临时文件.



5> Daniel Trebb..:

正如@JonathanWright 指出的那样,解决方案存在竞争条件:

创建一个临时文件GetTempFileName(),删除它,并创建一个具有相同名称的文件夹

使用GetRandomFileName()Guid.NewGuid.ToString创建随机文件夹名称,检查它是否存在,如果不存在则创建它.

但是,可以通过使用Transactional NTFS(TxF)API 以原子方式创建唯一的临时目录.

TxF有一个CreateDirectoryTransacted()可以通过Platform Invoke调用的函数.为此,我调整了Mohammad Elsheimy的电话代码CreateFileTransacted():

// using System.ComponentModel;
// using System.Runtime.InteropServices;
// using System.Transactions;

[ComImport]
[Guid("79427a2b-f895-40e0-be79-b57dc82ed231")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IKernelTransaction
{
    void GetHandle(out IntPtr pHandle);
}

// 2.2 Win32 Error Codes 
public const int ERROR_PATH_NOT_FOUND = 0x3;
public const int ERROR_ALREADY_EXISTS = 0xb7;
public const int ERROR_EFS_NOT_ALLOWED_IN_TRANSACTION = 0x1aaf;

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool CreateDirectoryTransacted(string lpTemplateDirectory, string lpNewDirectory, IntPtr lpSecurityAttributes, IntPtr hTransaction);

/// 
/// Creates a uniquely-named directory in the directory named by  and returns the path to it.
/// 
/// Path of a directory in which the temporary directory will be created.
/// The path of the newly-created temporary directory within .
public static string GetTempDirectoryName(string tempPath)
{
    string retPath;

    using (TransactionScope transactionScope = new TransactionScope())
    {
        IKernelTransaction kernelTransaction = (IKernelTransaction)TransactionInterop.GetDtcTransaction(Transaction.Current);
        IntPtr hTransaction;
        kernelTransaction.GetHandle(out hTransaction);

        while (!CreateDirectoryTransacted(null, retPath = Path.Combine(tempPath, Path.GetRandomFileName()), IntPtr.Zero, hTransaction))
        {
            int lastWin32Error = Marshal.GetLastWin32Error();
            switch (lastWin32Error)
            {
                case ERROR_ALREADY_EXISTS:
                    break;
                default:
                    throw new Win32Exception(lastWin32Error);
            }
        }

        transactionScope.Complete();
    }
    return retPath;
}

/// 
/// Equivalent to GetTempDirectoryName(Path.GetTempPath()).
/// 
/// 
public static string GetTempDirectoryName()
{
    return GetTempDirectoryName(Path.GetTempPath());
}

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