create c# .net temporary-files

create - c# temp folder



¿Cómo elimino automáticamente los tempfiles en c#? (9)

Es bueno ver que quieres ser responsable, pero si los archivos no son enormes (> 50MB) estarías en línea con todos (MS incluido) al dejarlos en el directorio temporal. El espacio en disco es abundante.

Como se publicó csl, GetTempPath es el camino a seguir. Los usuarios con poco espacio podrán ejecutar la limpieza del disco y sus archivos (junto con los de los demás) se limpiarán.

¿Cuál es una buena manera de garantizar que se elimine un archivo temporal si mi aplicación se cierra o se bloquea? Idealmente, me gustaría obtener un archivo temporal, usarlo y luego olvidarlo.

En este momento, conservo una lista de mis tempfiles y los elimino con un manejador de eventos que se desencadena en Application.ApplicationExit.

¿Hay una mejor manera?


No soy principalmente un programador de C #, pero en C ++ usaría RAII para esto. Hay algunos consejos sobre el uso del comportamiento tipo RAII en C # en línea, pero la mayoría parece usar el finalizador, que no es determinista.

Creo que hay algunas funciones de Windows SDK para crear archivos temporales, pero no sé si se eliminan automáticamente al finalizar el programa. Existe la función GetTempPath , pero los archivos solo se eliminan al cerrar sesión o reiniciarse, IIRC.

PD: La documentación del destructor de C # dice que puede y debe liberar recursos allí, lo que me parece un poco extraño. Si es así, simplemente puede eliminar el archivo temporal en el destructor, pero nuevamente, esto podría no ser completamente determinista.


Podría iniciar un hilo en el inicio que borrará los archivos que existen cuando "no deberían" recuperarse de su bloqueo.


Puede P / Invocar CreateFile y pasar el indicador FILE_FLAG_DELETE_ON_CLOSE . Esto le dice a Windows que elimine el archivo una vez que se hayan cerrado todos los identificadores. Ver también: Win32 CreateFile docs .


No se garantiza nada si el proceso se mata prematuramente, sin embargo, uso " using " para hacer esto ...

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

Ahora, cuando se elimina el archivo TempFile o se recoge basura, el archivo se elimina (si es posible). Obviamente, puedes utilizar esto tan estrechamente como quieras, o en una colección en alguna parte.


Yo uso una solución más confiable:

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

Cada vez que necesite uso de archivos temporales:

var tempFile = TemporaryFiles.UseNew();

Para asegurarse de que todos los archivos temporales se eliminan después de que la aplicación se cierra o se cuelga.

TemporaryFiles.DeleteAllPreviouslyUsed();

al inicio de la aplicación.


Si está creando una aplicación de Windows Forms, puede usar este código:

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


Considere usar el indicador 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


Utilizaría la clase .NET TempFileCollection , ya que está incorporada, disponible en las versiones anteriores de .NET, e implementa la interfaz IDisposable y, por lo tanto, se limpia después si se utiliza, por ejemplo, junto con la palabra clave "using" .

Aquí hay un ejemplo que extrae texto de un recurso incrustado (agregado a través de las páginas de propiedades de los proyectos -> pestaña Recursos como se describe aquí: ¿Cómo incrustar un archivo de texto en un ensamblado .NET? Y luego configurarlo como "EmbeddedResource" en la configuración de propiedad del archivo incrustado )

// 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."); }