0

I need to create three temporary XML files for debugging purposes. I'm using a TempFileCollection as it fits the bill, but apparently the AddExtension method doesn't actually return unique file names.

According to the MSDN:

This method can be called only once for each file name extension, because it will return the same name if it is called with the same extension.

Apparently I just have to add my own files anyway using the AddFile method. What's the use of this method then? To work around it I'm just using

var filename = Guid.NewGuid().ToString + ".xml"
collection.AddFile(filename, false);
Wesley Lomax
  • 2,067
  • 2
  • 20
  • 34
Cellivar
  • 568
  • 10
  • 27
  • careful! `Guid` isn't *guaranteed* to be unique. (although it's very unlikely that it won't be). – Timothy Groote Oct 30 '15 at 09:04
  • Indeed, but for the rare debugging session I'm doing on this project security isn't an issue and files are removed at the end of the session anyhow. – Cellivar Oct 30 '15 at 09:05

3 Answers3

1

Per TempFileCollection doc in MSDN:

To generate a unique name for a temporary file of a particular file extension, call AddExtension and specifiy the extension of the file name to generate. The AddExtension method will return a string consisting of a full path to a file name of the specified extension in the directory specified by the TempDir property. The AddExtension method will only return one unique file name per file name extension.

TempFileCollection is in System.CodeDom.Compiler namespace. If you just want to create some temp files, use Path.GetTempFileName.

Console.WriteLine(Path.ChangeExtension(Path.GetTempFileName(), "xml"));
Console.WriteLine(Path.ChangeExtension(Path.GetTempFileName(), "xml"));
Console.WriteLine(Path.ChangeExtension(Path.GetTempFileName(), "xml"));
// You got three different files with .xml extension.

Files created by Path.GetTempFileName() will NOT be delete automatically. To clean up temp files automatically, use System.IO.FileOptions.DeleteOnClose. See similar question at Windows temporary files behaviour - are they deleted by the system?. A piece of sample code is like this

var path = Path.GetTempFileName();
Console.WriteLine(path);
using (var fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, 4000, 
    FileOptions.DeleteOnClose))
{
    fs.WriteByte(65);
}

I know it's silly to include other unrelated parameters, but it's how this API designed. You can wrap fs in other steam or pass it to XDocument/XElement.Save()

var e = new XElement("Node");
e.Save(fs);
Community
  • 1
  • 1
qxg
  • 6,955
  • 1
  • 28
  • 36
  • I'm using the TempFileCollection object simply because it does what I need: clean up temp files automatically when done with them. Why rewrite things when someone else already handled it? My question is specifically asking for the utility of such a method. The signature of the method (input an extension, whether to keep the file, and get back a file name) seems to imply that it's generating a new file for you each time. As it turns out it'll only create one unique file and keep returning that. Doesn't make any sense to me. – Cellivar Oct 30 '15 at 09:17
  • 1
    @MrDoom, If you want them to be deleted automatically, use `System.IO.FileOptions.DeleteOnClose`. See more at http://stackoverflow.com/questions/324045/windows-temporary-files-behaviour-are-they-deleted-by-the-system. – qxg Oct 30 '15 at 09:30
0

The TempFileCollection is not meant to create temporary fileNames for you, it will hold only the temporary files and will delete them upon request in Delete() or when the collection is disposed. See a.o. property KeepFiles.

To generate unique filenames use System.IO.Path.GetTempFileName and System.IO.Path.changeExtension

Harald Coppoolse
  • 28,834
  • 7
  • 67
  • 116
  • But it apparently will, as the first call to AddExtension *will* return a uniquely named file. The second call onwards just returns the same file though. I understand I need to perform external steps to do it myself, however what is the purpose of AddExtension at that point? Some form of pooling? – Cellivar Oct 30 '15 at 09:27
0

TempFileCollection is in System.CodeDom.Compiler namespace. This implies it is there for the compiler to use.

Based on that, I can view two different use cases for TempFileCollection:

  • Creating a set of unrelated temp files, and ensuring they are cleaned up after.
  • Creating a set of related files with different extensions, and ensuring they are cleaned up after.

For the 2nd item (related files), just look at the bin and obj folders. You might have multiple files that correspond to the same file. For example:

  • Program.exe
  • Program.exe.config
  • Program.pdb

So, I would create a single TempFileCollection for all of the files that relate to Program. Then, I can call AddExtension to get the temp file for the .exe file. I don't need to store that path in a variable - I can just call AddExtension again, to get the same path.

TL;DR:

  • Use AddFile for the first use case (unrelated temp file)
  • Use AddExtension for the second use case (related temp files, all with unique extensions)
Mike Christiansen
  • 1,104
  • 2
  • 13
  • 30