How can I create a temp file with a specific extension with .NET?

后端 未结 17 1911
北恋
北恋 2020-11-28 01:49

I need to generate a unique temporary file with a .csv extension.

What I do right now is

string filename = System.IO.Path.GetTempFileName().Replace(         


        
相关标签:
17条回答
  • 2020-11-28 02:11

    The MSDN documentation for C++'s GetTempFileName discusses your concern and answers it:

    GetTempFileName is not able to guarantee that the file name is unique.

    Only the lower 16 bits of the uUnique parameter are used. This limits GetTempFileName to a maximum of 65,535 unique file names if the lpPathName and lpPrefixString parameters remain the same.

    Due to the algorithm used to generate file names, GetTempFileName can perform poorly when creating a large number of files with the same prefix. In such cases, it is recommended that you construct unique file names based on GUIDs.

    0 讨论(0)
  • 2020-11-28 02:11

    In my opinion, most answers proposed here as sub-optimal. The one coming closest is the original one proposed initially by Brann.

    A Temp Filename must be

    • Unique
    • Conflict-free (not already exist)
    • Atomic (Creation of Name & File in the same operation)
    • Hard to guess

    Because of these requirements, it is not a godd idea to program such a beast on your own. Smart People writing IO Libraries worry about things like locking (if needed) etc. Therefore, I see no need to rewrite System.IO.Path.GetTempFileName().

    This, even if it looks clumsy, should do the job:

    //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);
    
    0 讨论(0)
  • 2020-11-28 02:13

    This seems to work fine for me: it checks for file existance and creates the file to be sure it's a writable location. Should work fine, you can change it to return directly the FileStream (which is normally what you need for a temp file):

    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
    
    0 讨论(0)
  • 2020-11-28 02:14

    Try this function ...

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

    It will return a full path with the extension of your choice.

    Note, it's not guaranteed to produce a unique file name since someone else could have technically already created that file. However the chances of someone guessing the next guid produced by your app and creating it is very very low. It's pretty safe to assume this will be unique.

    0 讨论(0)
  • 2020-11-28 02:14

    You can also do the following

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

    and this also works as expected

    string filename = Path.ChangeExtension(Path.GetTempPath() + Guid.NewGuid().ToString(), ".csv");
    
    0 讨论(0)
  • 2020-11-28 02:15

    Guaranteed to be (statistically) unique:

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

    (To quote from the wiki article on the probabilty of a collision:

    ...one's annual risk of being hit by a meteorite is estimated to be one chance in 17 billion [19], that means the probability is about 0.00000000006 (6 × 10−11), equivalent to the odds of creating a few tens of trillions of UUIDs in a year and having one duplicate. In other words, only after generating 1 billion UUIDs every second for the next 100 years, the probability of creating just one duplicate would be about 50%. The probability of one duplicate would be about 50% if every person on earth owns 600 million UUIDs

    EDIT: Please also see JaredPar's comments.

    0 讨论(0)
提交回复
热议问题