this.Blog.Find(entry => entry.IsHelpful);
 Friday, August 08, 2008
Using Temp directories in .Net

Have you ever found the need to use a temporary directory on the file system in your code?  This issue came up with me recently (and bit me in the ass), so I thought I would share some experiences on how I overcame the problem. 

At the root of the problem is that you need some sort of permanent storage, but nothing that is stringent enough to require it reside in some "known" directory where it can be accessed at a later time.  You don't really care where you store a file, but you need to store it somewhere. 

I recently came across a piece of code in a unit test that serialized a class using the XmlSerializer.  The person who wrote the test must have wanted to see what the class looked like in serialized form.  The code was written so that the xml version of the class was dumped to the file system.  However, when the test was written, the file was hard-coded to the C:\Temp directory. 

As part of my task, I was incorporating the unit tests on this component into the continuous build.  Guess what happened when the test was moved the build server?  FAIL!!!  No C:\Temp directory on that machine means lots of red on the build server and the IT director screaming WTF?!?!?

The lesson is, never make assumptions when accessing the file system.  In this case, the test was counting on the directory both existing and the user having permissions to it.  Obviously, that's not a good idea.

There are other ways to get to a valid "temporary" directory in .Net.  The following code sample shows how you can try a few known places in .Net that should work as "temporary" directories.

/// <summary>
/// Get a valid "temporary" directory on the machine that is running this code 
/// </summary>
/// <returns>a temporary directory</returns>
private string GetTemporaryDirectory() 
{ 
    // try this first 
    string dir = Path.GetTempPath(); 
    if ( String.IsNullOrEmpty(dir) || !Directory.Exists(dir) ) 
    { 
        // see if the "TEMP" environment variable is set 
        dir = Environment.GetEnvironmentVariable("TEMP"); 
        if ( String.IsNullOrEmpty(dir) || !Directory.Exists(dir) ) 
        { 
            // hmmm ... let's create one in "My Documents" 
            string myDocsDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); 
            if ( String.IsNullOrEmpty(myDocsDir) || !Directory.Exists(myDocsDir) ) 
            { 
                // no "My Documents" directory??? 
                throw new Exception( 
                    "Cannot determine a valid temporary directory on this system. " + 
                    "Please set a valid directory for the \"TEMP\" environment variable."); 
            } 
            dir = String.Format("{0}\\Temp", myDocsDir); 
            if ( !Directory.Exists(dir) ) 
            { 
                Log.Info("Creating new Temp directory in {0}", myDocsDir); 
                Directory.CreateDirectory(dir); 
            }  
        } 
    } 
    if ( dir.EndsWith("\\") ) 
    { 
        // cut the last char off 
        dir = dir.Substring(0, dir.Length - 1); 
    } 
    return dir; 
}

The code example above tries to use the .Net libraries to query the file system for some well-known directories that can be used for temporary files.  If a valid one is not found, it will try to create a "Temp" directory in the current user's "My Documents" directory.  At worst, the user should have access to this directory, and the build should not break based on a hard-coded assumption.


Kick it on DotNetKicks.com
Friday, August 08, 2008 12:46:30 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  .Net | C#