@ Крис. Я тоже был одержим удаленным риском, что временный каталог может уже существовать. Дискуссии о случайных и криптографически сильных мне тоже не совсем устраивают.
Мой подход основывается на фундаментальном факте, что O / S не должен позволять 2 вызовам создать файл, чтобы оба были успешными. Немного удивительно, что разработчики .NET решили скрыть функциональность Win32 API для каталогов, что значительно упрощает эту задачу, поскольку возвращает ошибку при попытке создать каталог во второй раз. Вот что я использую:
[DllImport(@"kernel32.dll", EntryPoint = "CreateDirectory", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CreateDirectoryApi
([MarshalAs(UnmanagedType.LPTStr)] string lpPathName, IntPtr lpSecurityAttributes);
/// <summary>
/// Creates the directory if it does not exist.
/// </summary>
/// <param name="directoryPath">The directory path.</param>
/// <returns>Returns false if directory already exists. Exceptions for any other errors</returns>
/// <exception cref="System.ComponentModel.Win32Exception"></exception>
internal static bool CreateDirectoryIfItDoesNotExist([NotNull] string directoryPath)
{
if (directoryPath == null) throw new ArgumentNullException("directoryPath");
// First ensure parent exists, since the WIN Api does not
CreateParentFolder(directoryPath);
if (!CreateDirectoryApi(directoryPath, lpSecurityAttributes: IntPtr.Zero))
{
Win32Exception lastException = new Win32Exception();
const int ERROR_ALREADY_EXISTS = 183;
if (lastException.NativeErrorCode == ERROR_ALREADY_EXISTS) return false;
throw new System.IO.IOException(
"An exception occurred while creating directory'" + directoryPath + "'".NewLine() + lastException);
}
return true;
}
Вы сами решаете, стоит ли "цена / риск" неуправляемого кода p / invoke. Большинство скажет, что это не так, но, по крайней мере, теперь у вас есть выбор.
CreateParentFolder () оставлен студенту в качестве упражнения. Я использую Directory.CreateDirectory (). Будьте осторожны при получении родительского элемента каталога, так как в корне он равен нулю.