Using the .net framework you have the option to create temporary files with
Path.GetTempFileName();
The MSDN doesn't tell us what happens to temporary files. I remember reading somewhere that they are deleted by the OS when it gets a restart. Is this true?
If the files aren't deleted by the OS, why are they called temporary? They are normal files in a normal directory.
No, there's nothing turned on by default in Windows that will automatically delete temp files. Not on shutdown, not on reboot, not ever. The Disk Cleanup tool has an option to do that when its run.
Too many temp files can consume valuable storage space. By default, temp files aren't automatically deleted. They are automatically created, but neither operating systems nor programs delete them automatically. As a result, they can accumulate over time while taking up valuable space on your computer's storage drive.
These temporary attachment files might need to stay around indefinitely, if the user never closes the associated application. Show activity on this post. It's completely safe, and your instinct is 100% correct--this is the way to handle temp files, as long as you remember to clean them up afterwards.
The short answer: they don't get deleted.
The long answer: The managed Path.GetTempFileName()
method calls the native Win32API GetTempFileName()
method, like this:
//actual .NET 2.0 decompiled code // .NET Reflector rocks for looking at plumbing public static string GetTempFileName() { string tempPath = GetTempPath(); new FileIOPermission(FileIOPermissionAccess.Write, tempPath).Demand(); StringBuilder tmpFileName = new StringBuilder(260); if (Win32Native.GetTempFileName(tempPath, "tmp", 0, tmpFileName) == 0) { __Error.WinIOError(); } return tmpFileName.ToString(); }
The documentation for the native method states:
Temporary files whose names have been created by this function are not automatically deleted. To delete these files call DeleteFile.
I have found a great article called "Those pesky temp files" (Archived Oct. 2007) that starts from basics and touches some less obvious problems of handling temporary files, like:
FileOption.DeleteOnClose
and let the kernel deal with it)FileAttributes.Temporary
)C# Code from article:
using System; using System.IO; using System.Security.Permissions; using System.Security.Principal; using System.Security.AccessControl; public static class PathUtility { private const int defaultBufferSize = 0x1000; // 4KB #region GetSecureDeleteOnCloseTempFileStream /// <summary> /// Creates a unique, randomly named, secure, zero-byte temporary file on disk, which is automatically deleted when it is no longer in use. Returns the opened file stream. /// </summary> /// <remarks> /// <para>The generated file name is a cryptographically strong, random string. The file name is guaranteed to be unique to the system's temporary folder.</para> /// <para>The <see cref="GetSecureDeleteOnCloseTempFileStream"/> method will raise an <see cref="IOException"/> if no unique temporary file name is available. Although this is possible, it is highly improbable. To resolve this error, delete all uneeded temporary files.</para> /// <para>The file is created as a zero-byte file in the system's temporary folder.</para> /// <para>The file owner is set to the current user. The file security permissions grant full control to the current user only.</para> /// <para>The file sharing is set to none.</para> /// <para>The file is marked as a temporary file. File systems avoid writing data back to mass storage if sufficient cache memory is available, because an application deletes a temporary file after a handle is closed. In that case, the system can entirely avoid writing the data. Otherwise, the data is written after the handle is closed.</para> /// <para>The system deletes the file immediately after it is closed or the <see cref="FileStream"/> is finalized.</para> /// </remarks> /// <returns>The opened <see cref="FileStream"/> object.</returns> public static FileStream GetSecureDeleteOnCloseTempFileStream() { return GetSecureDeleteOnCloseTempFileStream(defaultBufferSize, FileOptions.DeleteOnClose); } /// <summary> /// Creates a unique, randomly named, secure, zero-byte temporary file on disk, which is automatically deleted when it is no longer in use. Returns the opened file stream with the specified buffer size. /// </summary> /// <remarks> /// <para>The generated file name is a cryptographically strong, random string. The file name is guaranteed to be unique to the system's temporary folder.</para> /// <para>The <see cref="GetSecureDeleteOnCloseTempFileStream"/> method will raise an <see cref="IOException"/> if no unique temporary file name is available. Although this is possible, it is highly improbable. To resolve this error, delete all uneeded temporary files.</para> /// <para>The file is created as a zero-byte file in the system's temporary folder.</para> /// <para>The file owner is set to the current user. The file security permissions grant full control to the current user only.</para> /// <para>The file sharing is set to none.</para> /// <para>The file is marked as a temporary file. File systems avoid writing data back to mass storage if sufficient cache memory is available, because an application deletes a temporary file after a handle is closed. In that case, the system can entirely avoid writing the data. Otherwise, the data is written after the handle is closed.</para> /// <para>The system deletes the file immediately after it is closed or the <see cref="FileStream"/> is finalized.</para> /// </remarks> /// <param name="bufferSize">A positive <see cref="Int32"/> value greater than 0 indicating the buffer size.</param> /// <returns>The opened <see cref="FileStream"/> object.</returns> public static FileStream GetSecureDeleteOnCloseTempFileStream(int bufferSize) { return GetSecureDeleteOnCloseTempFileStream(bufferSize, FileOptions.DeleteOnClose); } /// <summary> /// Creates a unique, randomly named, secure, zero-byte temporary file on disk, which is automatically deleted when it is no longer in use. Returns the opened file stream with the specified buffer size and file options. /// </summary> /// <remarks> /// <para>The generated file name is a cryptographically strong, random string. The file name is guaranteed to be unique to the system's temporary folder.</para> /// <para>The <see cref="GetSecureDeleteOnCloseTempFileStream"/> method will raise an <see cref="IOException"/> if no unique temporary file name is available. Although this is possible, it is highly improbable. To resolve this error, delete all uneeded temporary files.</para> /// <para>The file is created as a zero-byte file in the system's temporary folder.</para> /// <para>The file owner is set to the current user. The file security permissions grant full control to the current user only.</para> /// <para>The file sharing is set to none.</para> /// <para>The file is marked as a temporary file. File systems avoid writing data back to mass storage if sufficient cache memory is available, because an application deletes a temporary file after a handle is closed. In that case, the system can entirely avoid writing the data. Otherwise, the data is written after the handle is closed.</para> /// <para>The system deletes the file immediately after it is closed or the <see cref="FileStream"/> is finalized.</para> /// <para>Use the <paramref name="options"/> parameter to specify additional file options. You can specify <see cref="FileOptions.Encrypted"/> to encrypt the file contents using the current user account. Specify <see cref="FileOptions.Asynchronous"/> to enable overlapped I/O when using asynchronous reads and writes.</para> /// </remarks> /// <param name="bufferSize">A positive <see cref="Int32"/> value greater than 0 indicating the buffer size.</param> /// <param name="options">A <see cref="FileOptions"/> value that specifies additional file options.</param> /// <returns>The opened <see cref="FileStream"/> object.</returns> public static FileStream GetSecureDeleteOnCloseTempFileStream(int bufferSize, FileOptions options) { FileStream fs = GetSecureFileStream(Path.GetTempPath(), bufferSize, options | FileOptions.DeleteOnClose); File.SetAttributes(fs.Name, File.GetAttributes(fs.Name) | FileAttributes.Temporary); return fs; } #endregion #region GetSecureTempFileStream public static FileStream GetSecureTempFileStream() { return GetSecureTempFileStream(defaultBufferSize, FileOptions.None); } public static FileStream GetSecureTempFileStream(int bufferSize) { return GetSecureTempFileStream(bufferSize, FileOptions.None); } public static FileStream GetSecureTempFileStream(int bufferSize, FileOptions options) { FileStream fs = GetSecureFileStream(Path.GetTempPath(), bufferSize, options); File.SetAttributes(fs.Name, File.GetAttributes(fs.Name) | FileAttributes.NotContentIndexed | FileAttributes.Temporary); return fs; } #endregion #region GetSecureTempFileName public static string GetSecureTempFileName() { return GetSecureTempFileName(false); } public static string GetSecureTempFileName(bool encrypted) { using (FileStream fs = GetSecureFileStream(Path.GetTempPath(), defaultBufferSize, encrypted ? FileOptions.Encrypted : FileOptions.None)) { File.SetAttributes(fs.Name, File.GetAttributes(fs.Name) | FileAttributes.NotContentIndexed | FileAttributes.Temporary); return fs.Name; } } #endregion #region GetSecureFileName public static string GetSecureFileName(string path) { return GetSecureFileName(path, false); } public static string GetSecureFileName(string path, bool encrypted) { using (FileStream fs = GetSecureFileStream(path, defaultBufferSize, encrypted ? FileOptions.Encrypted : FileOptions.None)) { return fs.Name; } } #endregion #region GetSecureFileStream public static FileStream GetSecureFileStream(string path) { return GetSecureFileStream(path, defaultBufferSize, FileOptions.None); } public static FileStream GetSecureFileStream(string path, int bufferSize) { return GetSecureFileStream(path, bufferSize, FileOptions.None); } public static FileStream GetSecureFileStream(string path, int bufferSize, FileOptions options) { if (path == null) throw new ArgumentNullException("path"); if (bufferSize <= 0) throw new ArgumentOutOfRangeException("bufferSize"); if ((options & ~(FileOptions.Asynchronous | FileOptions.DeleteOnClose | FileOptions.Encrypted | FileOptions.RandomAccess | FileOptions.SequentialScan | FileOptions.WriteThrough)) != FileOptions.None) throw new ArgumentOutOfRangeException("options"); new FileIOPermission(FileIOPermissionAccess.Write, path).Demand(); SecurityIdentifier user = WindowsIdentity.GetCurrent().User; FileSecurity fileSecurity = new FileSecurity(); fileSecurity.AddAccessRule(new FileSystemAccessRule(user, FileSystemRights.FullControl, AccessControlType.Allow)); fileSecurity.SetAccessRuleProtection(true, false); fileSecurity.SetOwner(user); // Attempt to create a unique file three times before giving up. // It is highly improbable that there will ever be a name clash, // therefore we do not check to see if the file first exists. for (int attempt = 0; attempt < 3; attempt++) { try { return new FileStream(Path.Combine(path, Path.GetRandomFileName()), FileMode.CreateNew, FileSystemRights.FullControl, FileShare.None, bufferSize, options, fileSecurity); } catch (IOException) { if (attempt == 2) throw; } } // This code can never be reached. // The compiler thinks otherwise. throw new IOException(); } #endregion }
Based on the March files in my %tmp%, I'd say not.
Re why they are called temporary - because that is their expected usage. They aren't system files; they aren't application files, and they aren't user documents... they exist only to allow an app to do temporary processing (perhaps on large volumes of data), or often to pass data via IPC to another process. Hence they really are temporary.
You should aim to delete any temp files you create, fatal "kill" etc not withstanding. I often use "using" for this - I create a wrapper class - i.e.
sealed class TempFile : IDisposable { // formatted for space string path; public string Path { get { if(path==null) throw new ObjectDisposedException(GetType().Name); return path; } } public TempFile() : this(System.IO.Path.GetTempFileName()) { } public TempFile(string path) { if (string.IsNullOrEmpty(path)) throw new ArgumentNullException("path"); this.path = path; } private void Dispose(bool disposing) { if (path != null) { try { File.Delete(path); } catch { } // best endeavours... path = null; } } public void Dispose() { GC.SuppressFinalize(this); Dispose(true); } ~TempFile() { Dispose(false); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With