我如何自动删除C#中的临时文件?

如果我的应用程序closures或崩溃,确保临时文件被删除的好方法是什么? 理想情况下,我想获得一个临时文件,使用它,然后忘掉它。

现在我保存我的临时文件列表,并删除它们在Application.ApplicationExit上触发的事件处理程序。

有没有更好的办法?

没有任何保证,如果过程中过早死亡,但是,我用“ using ”来做到这一点..

 using System; using System.IO; sealed class TempFile : IDisposable { string path; public TempFile() : this(System.IO.Path.GetTempFileName()) { } public TempFile(string path) { if (string.IsNullOrEmpty(path)) throw new ArgumentNullException("path"); this.path = path; } public string Path { get { if (path == null) throw new ObjectDisposedException(GetType().Name); return path; } } ~TempFile() { Dispose(false); } public void Dispose() { Dispose(true); } private void Dispose(bool disposing) { if (disposing) { GC.SuppressFinalize(this); } if (path != null) { try { File.Delete(path); } catch { } // best effort path = null; } } } static class Program { static void Main() { string path; using (var tmp = new TempFile()) { path = tmp.Path; Console.WriteLine(File.Exists(path)); } Console.WriteLine(File.Exists(path)); } } 

现在当TempFile被丢弃或垃圾收集时,文件被删除(如果可能的话)。 你可以明显地使用它,只要你喜欢,或者集合在某个地方。

考虑使用FileOptions.DeleteOnClose标志:

 using (FileStream fs = new FileStream(Path.GetTempFileName(), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.RandomAccess | FileOptions.DeleteOnClose)) { // temp file exists } // temp file is gone 

你可以P /调用CreateFile并传递FILE_FLAG_DELETE_ON_CLOSE标志。 这告诉Windows在所有句柄closures后删除文件。 另请参阅: Win32 CreateFile文档 。

我将使用.NET TempFileCollection类,因为它是内置的,可用于.NET的旧版本,并且实现了IDisposable接口,因此如果与"using"关键字结合使用,则会自行清理。

下面是一个从embedded式资源中提取文本的例子(通过项目属性页面添加 – > Resources标签,如下所述: 如何在.NET程序集中embedded文本文件 ,然后在embedded文件的属性设置中设置为"EmbeddedResource" )。

  // Extracts the contents of the embedded file, writes them to a temp file, executes it, and cleans up automatically on exit. private void ExtractAndRunMyScript() { string vbsFilePath; // By default, TempFileCollection cleans up after itself. using (var tempFiles = new System.CodeDom.Compiler.TempFileCollection()) { vbsFilePath= tempFiles.AddExtension("vbs"); // Using IntelliSense will display the name, but it's the file name // minus its extension. System.IO.File.WriteAllText(vbsFilePath, global::Instrumentation.Properties.Resources.MyEmbeddedFileNameWithoutExtension); RunMyScript(vbsFilePath); } System.Diagnostics.Debug.Assert(!File.Exists(vbsFilePath), @"Temp file """ + vbsFilePath+ @""" has not been deleted."); } 

我主要不是C#程序员,但在C ++中,我会使用RAII 。 在C#在线使用类似RAII的行为有一些提示 ,但大多数似乎使用终结者 – 这是不确定的。

我认为有一些Windows SDK函数来创build临时文件,但不知道它们是否在程序终止时自动删除。 有GetTempPathfunction,但只有当您注销或重新启动,IIRC文件时才会被删除。

PS C#析构函数文档说你可以并且应该释放那里的资源,我觉得有点奇怪。 如果是这样,你可以简单地删除析构函数中的临时文件,但是这可能不是完全确定的。

它很高兴看到你想负责任,但如果文件不是很大(> 50MB),你将在每个人(包括MS),把他们留在临时目录。 磁盘空间丰富。

正如csl发布,GetTempPath是要走的路。 空间不足的用户将能够运行磁盘清理,并且您的文件(以及其他所有人)将被清理。

我使用更可靠的解决scheme:

 using System.IO; using System.Reflection; namespace Konard.Helpers { public static partial class TemporaryFiles { private const string UserFilesListFilenamePrefix = ".used-temporary-files.txt"; static private readonly object UsedFilesListLock = new object(); private static string GetUsedFilesListFilename() { return Assembly.GetEntryAssembly().Location + UserFilesListFilenamePrefix; } private static void AddToUsedFilesList(string filename) { lock (UsedFilesListLock) { using (var writer = File.AppendText(GetUsedFilesListFilename())) writer.WriteLine(filename); } } public static string UseNew() { var filename = Path.GetTempFileName(); AddToUsedFilesList(filename); return filename; } public static void DeleteAllPreviouslyUsed() { lock (UsedFilesListLock) { var usedFilesListFilename = GetUsedFilesListFilename(); if (!File.Exists(usedFilesListFilename)) return; using (var listFile = File.Open(usedFilesListFilename, FileMode.Open)) { using (var reader = new StreamReader(listFile)) { string tempFileToDelete; while ((tempFileToDelete = reader.ReadLine()) != null) { if (File.Exists(tempFileToDelete)) File.Delete(tempFileToDelete); } } } // Clean up using (File.Open(usedFilesListFilename, FileMode.Truncate)) { } } } } } 

每次你需要临时文件使用:

 var tempFile = TemporaryFiles.UseNew(); 

确保应用程序closures或崩溃后,所有临时文件都被删除

 TemporaryFiles.DeleteAllPreviouslyUsed(); 

在申请的开始。

您可以在启动时启动一个线程,删除存在于“不应该”从崩溃中恢复的文件。

如果您正在构buildWindows窗体应用程序,则可以使用以下代码:

  private void Form1_FormClosing(object sender, FormClosingEventArgs e) { File.Delete("temp.data"); }