guardar gettemppath gettempfilename filename create archivo c# .net temporary-files

gettemppath - guardar archivo temporal c#



¿Cómo puedo crear un archivo temporal con una extensión específica con.NET? (14)

¿Por qué no comprobar si el archivo existe?

string fileName; do { fileName = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".csv"; } while (System.IO.File.Exists(fileName));

Necesito generar un archivo temporal único con una extensión .csv.

Lo que hago ahora es

string filename = System.IO.Path.GetTempFileName().Replace(".tmp", ".csv");

Sin embargo, esto no garantiza que mi archivo .csv sea único.

Sé que las posibilidades de colisión son muy bajas (especialmente si consideras que no elimino los archivos .tmp), pero este código no me parece bien.

Por supuesto, podría generar manualmente nombres de archivos aleatorios hasta que finalmente encuentre uno único (lo que no debería ser un problema), pero tengo curiosidad por saber si otros han encontrado una buena manera de lidiar con este problema.


Creo que deberías intentar esto:

string path = Path.GetRandomFileName(); path = Path.Combine(@"c:/temp", path); path = Path.ChangeExtension(path, ".tmp"); File.Create(path);

Genera un nombre de archivo único y crea un archivo con ese nombre de archivo en una ubicación específica.


En mi opinión, la mayoría de las respuestas se proponen aquí como subóptimas. El que más se acerca es el original propuesto inicialmente por Brann.

Un nombre de archivo temporal debe ser

  • Único
  • Libre de conflictos (no existe ya)
  • Atómico (Creación de Nombre y Archivo en la misma operación)
  • Difícil de adivinar

Debido a estos requisitos, no es una buena idea programar tal bestia por tu cuenta. Las personas inteligentes que escriben bibliotecas IO se preocupan por cosas como el bloqueo (si es necesario), etc. Por lo tanto, no veo la necesidad de volver a escribir System.IO.Path.GetTempFileName ().

Esto, incluso si parece torpe, debería hacer el trabajo:

//Note that this already *creates* the file string filename1 = System.IO.Path.GetTempFileName() // Rename and move filename = filename.Replace(".tmp", ".csv"); File.Move(filename1 , filename);


Esta es una forma simple pero efectiva de generar nombres de archivos incrementales. Se buscará directamente en el actual (puede señalarlo fácilmente en otro lugar) y buscar archivos con la base YourApplicationName * .txt (de nuevo, puede cambiarlo fácilmente). Comenzará a las 0000, de modo que el primer nombre de archivo será YourApplicationName0000.txt. Si, por alguna razón, hay nombres de archivos con datos no deseados entre las partes izquierda y derecha (es decir, no los números), esos archivos se ignorarán en virtud de la llamada tripartita.

public static string CreateNewOutPutFile() { const string RemoveLeft = "YourApplicationName"; const string RemoveRight = ".txt"; const string searchString = RemoveLeft + "*" + RemoveRight; const string numberSpecifier = "0000"; int maxTempNdx = -1; string fileName; string [] Files = Directory.GetFiles(Directory.GetCurrentDirectory(), searchString); foreach( string file in Files) { fileName = Path.GetFileName(file); string stripped = fileName.Remove(fileName.Length - RemoveRight.Length, RemoveRight.Length).Remove(0, RemoveLeft.Length); if( int.TryParse(stripped,out int current) ) { if (current > maxTempNdx) maxTempNdx = current; } } maxTempNdx++; fileName = RemoveLeft + maxTempNdx.ToString(numberSpecifier) + RemoveRight; File.CreateText(fileName); // optional return fileName; }


Esto es lo que estoy haciendo:

string tStamp = String.Format("{0:yyyyMMdd.HHmmss}", DateTime.Now); string ProcID = Process.GetCurrentProcess().Id.ToString(); string tmpFolder = System.IO.Path.GetTempPath(); string outFile = tmpFolder + ProcID + "_" + tStamp + ".txt";


Esto parece funcionar bien para mí: comprueba la existencia del archivo y crea el archivo para asegurarse de que sea una ubicación de escritura. Si funciona bien, puede cambiarlo para devolver directamente FileStream (que normalmente es lo que necesita para un archivo temporal):

private string GetTempFile(string fileExtension) { string temp = System.IO.Path.GetTempPath(); string res = string.Empty; while (true) { res = string.Format("{0}.{1}", Guid.NewGuid().ToString(), fileExtension); res = System.IO.Path.Combine(temp, res); if (!System.IO.File.Exists(res)) { try { System.IO.FileStream s = System.IO.File.Create(res); s.Close(); break; } catch (Exception) { } } } return res; } // GetTempFile


Esto podría ser útil para usted ... Es crear una temperatura. y devuélvalo como una cadena en VB.NET.

Fácilmente convertible a C #:

Public Function GetTempDirectory() As String Dim mpath As String Do mpath = System.IO.Path.Combine(System.IO.Path.GetTempPath, System.IO.Path.GetRandomFileName) Loop While System.IO.Directory.Exists(mpath) Or System.IO.File.Exists(mpath) System.IO.Directory.CreateDirectory(mpath) Return mpath End Function


Garantizado para ser (estadísticamente) único:

string fileName = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".csv";

(Para citar del artículo wiki sobre la probabilidad de una colisión:

... se estima que el riesgo anual de ser golpeado por un meteorito es una posibilidad entre 17 mil millones [19], lo que significa que la probabilidad es de alrededor de 0.00000000006 (6 × 10−11), equivalente a la probabilidad de crear algunas decenas de trillones de UUID en un año y tener un duplicado. En otras palabras, solo después de generar 1 mil millones de UUID por segundo durante los próximos 100 años, la probabilidad de crear un solo duplicado sería aproximadamente del 50%. La probabilidad de un duplicado sería aproximadamente el 50% si cada persona en la tierra posee 600 millones de UUID

EDITAR: Por favor también vea los comentarios de JaredPar.


La documentación de MSDN para GetTempFileName de C ++ analiza su inquietud y la responde:

GetTempFileName no puede garantizar que el nombre del archivo sea único .

Solo se utilizan los 16 bits inferiores del parámetro uUnique. Esto limita GetTempFileName a un máximo de 65,535 nombres de archivos únicos si los parámetros lpPathName y lpPrefixString permanecen iguales.

Debido al algoritmo utilizado para generar nombres de archivos, GetTempFileName puede tener un bajo rendimiento al crear una gran cantidad de archivos con el mismo prefijo. En tales casos, se recomienda construir nombres de archivo únicos basados ​​en GUID .


Prueba esta función ...

public static string GetTempFilePathWithExtension(string extension) { var path = Path.GetTempPath(); var fileName = Guid.NewGuid().ToString() + extension; return Path.Combine(path, fileName); }

Volverá un camino completo con la extensión de su elección.

Tenga en cuenta que no se garantiza que se genere un nombre de archivo único, ya que alguien más podría haber creado ese archivo técnicamente. Sin embargo, las posibilidades de que alguien adivine el próximo guid producido por su aplicación y de crearlo son muy bajas. Es bastante seguro asumir que esto será único.


Qué tal si:

Path.Combine(Path.GetTempPath(), DateTime.Now.Ticks.ToString() + "_" + Guid.NewGuid().ToString() + ".csv")

Es altamente improbable que la computadora genere el mismo Guid en el mismo instante de tiempo. La única debilidad que veo aquí es el impacto en el rendimiento que agregará DateTime.Now.Ticks.


También puede usar System.CodeDom.Compiler.TempFileCollection como alternativa.

string tempDirectory = @"c://temp"; TempFileCollection coll = new TempFileCollection(tempDirectory, true); string filename = coll.AddExtension("txt", true); File.WriteAllText(Path.Combine(tempDirectory,filename),"Hello World");

Aquí utilicé una extensión txt pero puedes especificar lo que quieras. También puse el indicador de mantener en verdadero para que el archivo temporal se mantenga después de su uso. Desafortunadamente, TempFileCollection crea un archivo aleatorio por extensión. Si necesita más archivos temporales, puede crear varias instancias de TempFileCollection.


También puedes hacer lo siguiente.

string filename = Path.ChangeExtension(Path.GetTempFileName(), ".csv");

Y esto también funciona como se esperaba.

string filename = Path.ChangeExtension(Path.GetTempPath() + Guid.NewGuid().ToString(), ".csv");


public static string GetTempFileName(string extension) { int attempt = 0; while (true) { string fileName = Path.GetRandomFileName(); fileName = Path.ChangeExtension(fileName, extension); fileName = Path.Combine(Path.GetTempPath(), fileName); try { using (new FileStream(fileName, FileMode.CreateNew)) { } return fileName; } catch (IOException ex) { if (++attempt == 10) throw new IOException("No unique temporary file name is available.", ex); } } }

Nota: esto funciona como Path.GetTempFileName. Se crea un archivo vacío para reservar el nombre del archivo. Hace 10 intentos, en caso de colisiones generadas por Path.GetRandomFileName ();