Thanks for the suggestions. In the end, here's what I came up with:
/// <summary>
/// Creates a sequential filename. (a file with that name is created)
/// </summary>
/// <param name="folder">The folder.</param>
/// <returns></returns>
static string CreateSequentialFilename(string folder)
{
return CreateSequentialFilename(folder, false);
}
/// <summary>
/// Creates a sequential filename. (a file with that name is created)
/// </summary>
/// <param name="folder">The folder.</param>
/// <param name="useThreadId">if set to <c>true</c> the thread id is used in the filename.</param>
/// <returns>The filename (with path)</returns>
/// <remarks>This probably should be expanded to allow passing in a prefix and the extension</remarks>
static string CreateSequentialFilename(string folder, bool useThreadId)
{
string filePattern = "";
if (useThreadId)
{
// This pattern adds the thread ID in the middle. Use if multiple threads will be creating files at the same time.
filePattern = String.Format("{0:yyyy-MM-dd.HH-mm-ss}({1:X4}){{0:000}}.jpg", DateTime.Now, GetCurrentThreadId());
}
else
{
// This pattern has the date (dot) time (dot) sequential index number
filePattern = String.Format("{0:yyyy-MM-dd.HH-mm-ss}.{{0:000}}.jpg", DateTime.Now);
}
int n = 0;
do
{
string filename = Path.Combine(folder, string.Format(filePattern, ++n));
// Cycle through numbers until one is found which does not exist.
if (!File.Exists(filename))
{
// Try/catch is used for the case where between checking for the file's existence above, and
// creating it below, another process creates a file with the same name. In this case (which should never
// occur if the filePattern with the threadid is used above), File.Open will throw a IOException, inwhich case,
// we keep looking.
try
{
using (FileStream fs = File.Open(filename, FileMode.CreateNew))
{
// A file must be created, so the next time this is called, it will create a different name.
}
return filename;
}
catch (IOException )
{ /* just swallow it */ }
}
} while (true);
}
[DllImport("KERNEL32")]
public static extern int GetCurrentThreadId();