views:

1566

answers:

4

What's the best way to get a temp directory name in Windows? I see that I can use GetTempPath and GetTempFileName to create a temporary file, but is there any equivalent to the Linux / BSD mkdtemp function for creating a temporary directory?

A: 

GetTempPath is the correct way of doing it; I'm not sure what your concern about this method is. You can then use CreateDirectory to make it.

Will
One problem is that GetTempFileName will create a zero-byte file. You need to use GetTempPath, GetRandomFileName and CreateDirectory instead.
Scott Dorman
Which is fine, possible, and doable. I was going to provide code but Dorman got it before me, and it works correctly.
Will
+3  A: 

No, there is no equivalent to mkdtemp. The best option is to use a combination of GetTempPath and GetRandomFileName.

You would need code similar to this:

public string GetTemporaryDirectory()
{
   string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
   Directory.CreateDirectory(tempDirectory);
   return tempDirectory;
}
Scott Dorman
@Will: Thanks for the edit and correcting my typo! One too many copy/paste errors. :(
Scott Dorman
This seems a little dangerous. In particular, there's a chance (small, but non-zero, right?) that Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()) will return the name of a directory that already exists. Since Directory.CreateDirectory(tempDirectory) won't throw an exception if tempDirectory already exists, this case won't be detected by your application. And then you may have two applications stepping on each other's work.Is there any safer alternative in .NET?
Chris
@Chris: The GetRandomFileName method returns a cryptographically strong, random string that can be used as either a folder name or a file name. I suppose it's theoretically possible that the resulting path could already exist, but there are no other ways to do this. You could check to see if the path exists, and if it does call Path.GetRandomFileName() again, and repeat.
Scott Dorman
@Scott I think checking if the path exists isn't actually sufficient if you are truly obsessed with safety. Suppose you call Directory.Exists(tempDirectory) and learn that the directory doesn't yet exist. At this point another process could potentially sneak in and create the very directory you are about to create before you get to your call to Directory.CreateDirectory(). When control returns to your application, your call to CreateDirectory won't throw an exception, and the two applications will end up stepping on each other's toes. Seems unlikely in practice, yet it still bothers me a bit.
Chris
@Chris: Yes, if you are worried about security to that extent there is a **very** slim chance that another process could create the directory between the Path.Combine and the Directory.CreateDirectory calls.
Scott Dorman
A: 

As mentioned above, Path.GetTempPath() is one way to do it. You could also call Environment.GetEnvironmentVariable("TEMP") if the user has a TEMP environment variable set up.

If you are planning on using the temp directory as a means of persisting data in the application, you probably should look at using IsolatedStorage as a repository for configuration/state/etc...

Chris Rauber
+1  A: 

I like to use GetTempPath(), a GUID-creation function like CoCreateGuid(), and CreateDirectory().

A GUID is designed to have a high probability of uniqueness, and it's also highly improbable that someone would manually create a directory with the same form as a GUID (and if they do then CreateDirectory() will fail indicating its existence.)

Matthew