How to automatically remove tempfiles in c #?

What is a good way to guarantee that tempfile will be deleted if my application closes or crashes? Ideally, I would like to get a temporary file, use it, and then forget about it.

Now I save the list of my tempfiles and delete them using the event handler that launches Application.ApplicationExit.

Is there a better way?

+47
c # temporary-files
Dec 30 '09 at 12:20
source share
9 answers

Nothing is guaranteed if the process is killed early, however I use " using " to do this.

 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)); } } 

Now that the TempFile is deleted or garbage collected, the file is deleted (if possible). You could obviously use this as tightly limited as you like, or in some collection.

+66
Dec 30 '09 at 2:30 p.m.
source share

Consider using the FileOptions.DeleteOnClose flag:

 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 
+39
Aug 20 '14 at 18:14
source share

You can P / Invoke CreateFile and pass the flag FILE_FLAG_DELETE_ON_CLOSE . This tells Windows to delete the file after closing all descriptors. See Also: Win32 CreateFile docs .

+18
Dec 30 '09 at 14:45
source share

I would use the .NET TempFileCollection class because it is built-in, available in older versions of .NET and implements the IDisposable interface and thus cleans up after itself if used, for example. combined with the keyword "using" .

Here is an example that extracts text from an embedded resource (added through the project properties pages โ†’ the Resources tab, as described here: How to insert a text file into the .NET assembly ? , then set the value "EmbeddedResource" to the built-in properties of the file).

  // 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 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."); } 
+4
Apr 04 '14 at 0:32
source share

I am not a C # programmer, but in C ++ I would use RAII . There are some tips on using RAII-like behavior in C # on the Internet, but most of them seem to use finalizer - which is not deterministic.

I think there are some functions of the Windows SDK for creating temporary files, but I donโ€™t know if they are automatically deleted when the program ends. There is a GetTempPath function, but files there are only deleted when you log out or restart, IIRC.

PS C # destructor documentation says that you can and should allocate resources there, which I find a bit strange. If so, you can simply delete the temporary file in the destructor, but then again, it may not be completely deterministic.

+3
Dec 30 '09 at 12:46
source share

It's nice to see that you want to be responsible, but if the files are not huge (> 50 MB), you would correspond to all (including MS), leaving them in the temp directory. Disk space is plentiful.

As csl pointed out, GetTempPath is the way to go. Users with enough space will be able to run Disk Cleanup, and your files (along with everyone else) will be cleaned up.

+2
Dec 30 '09 at 13:10
source share

I am using a more robust solution:

 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)) { } } } } } 

Every time you need temporary use of a file:

 var tempFile = TemporaryFiles.UseNew(); 

To make sure that all temporary files are deleted after the application is closed or crashes, put

 TemporaryFiles.DeleteAllPreviouslyUsed(); 

at the beginning of the application.

+1
Nov 19 '14 at 13:54 on
source share

You can start a thread at startup, which will delete files that exist when they "should not" recover from your failure.

0
Dec 30 '09 at 16:54
source share

If you are building a Windows Forms application, you can use this code:

  private void Form1_FormClosing(object sender, FormClosingEventArgs e) { File.Delete("temp.data"); } 
-2
Jul 15 '15 at 18:27
source share



All Articles