@Chris. Tôi cũng bị ám ảnh với rủi ro từ xa rằng một thư mục tạm thời có thể đã tồn tại. Các cuộc thảo luận về ngẫu nhiên và mạnh mẽ về mật mã cũng không hoàn toàn thỏa mãn tôi.
Cách tiếp cận của tôi dựa trên thực tế cơ bản là O / S không được phép 2 cuộc gọi để tạo một tệp để cả hai thành công. Một điều đáng ngạc nhiên là các nhà thiết kế .NET đã chọn ẩn chức năng API Win32 cho các thư mục, điều này làm cho việc này dễ dàng hơn nhiều, vì nó trả về lỗi khi bạn cố gắng tạo thư mục lần thứ hai. Đây là những gì tôi sử dụng:
[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;
}
Bạn có thể quyết định liệu "chi phí / rủi ro" của mã p / invoke không được quản lý có xứng đáng hay không. Hầu hết sẽ nói rằng nó không phải, nhưng ít nhất bây giờ bạn có một sự lựa chọn.
CreateParentFolder () được để lại như một bài tập cho học sinh. Tôi sử dụng Directory.CreateDirectory (). Hãy cẩn thận nhận cha mẹ của một thư mục, vì nó là null khi ở gốc.