@Tokopedia Saya juga terobsesi dengan risiko jarak jauh bahwa direktori sementara mungkin sudah ada. Diskusi tentang acak dan kuat secara kriptografis juga tidak sepenuhnya memuaskan saya.
Pendekatan saya dibangun di atas fakta mendasar bahwa O / S tidak boleh mengizinkan 2 panggilan untuk membuat file agar keduanya berhasil. Sedikit mengherankan bahwa perancang .NET memilih untuk menyembunyikan fungsionalitas Win32 API untuk direktori, yang membuatnya lebih mudah, karena ini mengembalikan kesalahan saat Anda mencoba membuat direktori untuk kedua kalinya. Inilah yang saya gunakan:
[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;
}
Anda dapat memutuskan apakah "biaya / risiko" dari kode p / pemanggilan yang tidak dikelola sepadan. Sebagian besar akan mengatakan tidak, tetapi setidaknya Anda sekarang punya pilihan.
CreateParentFolder () ditinggalkan sebagai latihan untuk siswa. Saya menggunakan Directory.CreateDirectory (). Berhati-hatilah saat mendapatkan induk direktori, karena nilainya null saat berada di root.