[C#] .NET으로 특정 확장자를 가진 임시 파일을 어떻게 만들 수 있습니까?

확장명이 .csv 인 고유 한 임시 파일을 생성해야합니다.

내가 지금하는 일은

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

그러나 이것이 내 .csv 파일이 고유하다는 것을 보장하지는 않습니다.

충돌 가능성이 매우 낮다는 것을 알고 있습니다 (특히 .tmp 파일을 삭제하지 않는다고 생각하면).이 코드는 나에게 좋지 않습니다.

물론 문제가되지 않아야하는 고유 한 파일을 찾을 때까지 임의의 파일 이름을 수동으로 생성 할 수 있지만 다른 사람들이이 문제를 처리 할 수있는 좋은 방법을 찾았는지 궁금합니다.



답변

(통계적으로) 고유해야합니다.

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

(위반 기사에서 충돌의 확률에 대해 인용하려면 :

… 운석에 부딪 힐 수있는 연간 위험은 170 억으로 한 번의 확률로 추정됩니다. 1 년에 수 조조의 UUID가 있으며 하나의 복제본이 있습니다. 다시 말해, 향후 100 년 동안 초당 10 억 개의 UUID를 생성 한 후에 만 ​​하나의 복제본을 생성 할 확률은 약 50 %입니다. 지구상의 모든 사람이 6 억 UUID를 소유하고 있다면 한 번의 복제 확률은 약 50 %입니다.

편집 : JaredPar의 의견도 참조하십시오.


답변

이 기능을 사용해보십시오 …

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

선택한 확장명으로 전체 경로를 반환합니다.

다른 사람이 기술적으로 해당 파일을 이미 만들었을 수 있으므로 고유 한 파일 이름을 생성 할 수는 없습니다. 그러나 누군가가 앱에서 생성 한 다음 guid를 추측하여 만들 가능성은 매우 낮습니다. 이것이 유일하다고 가정하는 것이 꽤 안전합니다.


답변

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

참고 : 이것은 Path.GetTempFileName과 같이 작동합니다. 파일 이름을 예약하기 위해 빈 파일이 작성됩니다. Path.GetRandomFileName ()에 의해 생성 된 충돌의 경우 10 회 시도합니다.


답변

또는 System.CodeDom.Compiler.TempFileCollection을 대신 사용할 수도 있습니다 .

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

여기서는 txt 확장자를 사용했지만 원하는 것을 지정할 수 있습니다. 또한 사용 후 임시 파일이 유지되도록 keep 플래그를 true로 설정했습니다. 불행히도 TempFileCollection은 확장명마다 하나의 임의 파일을 만듭니다. 임시 파일이 더 필요한 경우 TempFileCollection의 여러 인스턴스를 만들 수 있습니다.


답변

파일이 존재하지 않는 이유는 무엇입니까?

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


답변

C ++의 GetTempFileName에 대한 MSDN 설명서 는 사용자의 우려 사항을 설명하고 이에 대한 답변을 제공합니다.

GetTempFileName은 파일 이름이 고유하다는 것을 보장 할 수 없습니다 .

uUnique 매개 변수의 하위 16 비트 만 사용됩니다. lpPathName 및 lpPrefixString 매개 변수가 동일하게 유지되면 GetTempFileName을 최대 65,535 개의 고유 파일 이름으로 제한합니다.

파일 이름을 생성하는 데 사용 된 알고리즘으로 인해 동일한 접두사로 많은 수의 파일을 만들 때 GetTempFileName의 성능이 저하 될 수 있습니다. 이러한 경우 GUID를 기반으로 고유 한 파일 이름을 구성하는 것이 좋습니다 .


답변

어때요?

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

컴퓨터가 동일한 순간에 동일한 Guid를 생성하는 것은 매우 불가능합니다. 내가 여기에 볼 수있는 유일한 약점은 DateTime.Now.Ticks가 성능에 미치는 영향입니다.