programing

Windows에서 임시 디렉토리를 작성하시겠습니까?

instargram 2023. 4. 22. 08:26
반응형

Windows에서 임시 디렉토리를 작성하시겠습니까?

Windows에서 임시 디렉토리 이름을 얻는 가장 좋은 방법은 무엇입니까?아, 그렇구나.GetTempPath그리고.GetTempFileName임시 파일을 작성하는데, 임시 디렉토리를 작성하기 위한 Linux / BSD 기능과 동등한 기능이 있습니까?

아니요, mkdtemp에 해당하는 것은 없습니다.가장 좋은 옵션은 GetTempPath와 GetRandomFileName을 조합하여 사용하는 것입니다.

다음과 같은 코드가 필요합니다.

public string GetTemporaryDirectory()
{
   string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
   Directory.CreateDirectory(tempDirectory);
   return tempDirectory;
}

나는 해킹을 한다Path.GetTempFileName()디스크에 유효한 유사 파일 경로를 지정한 후 파일을 삭제하고 동일한 파일 경로로 디렉토리를 만듭니다.

따라서 Scott Dorman의 답변에 대한 Chris의 코멘트에 따라 파일 경로를 잠시 동안 사용할 수 있는지 또는 루프할 필요가 없습니다.

public string GetTemporaryDirectory()
{
  string tempFolder = Path.GetTempFileName();
  File.Delete(tempFolder);
  Directory.CreateDirectory(tempFolder);

  return tempFolder;
}

암호학적으로 안전한 랜덤 이름이 정말 필요한 경우 Scott의 답변을 수정하여 잠시 사용하거나 do loop을 통해 디스크에 경로를 계속 생성할 수 있습니다.

CoCreateGuid()나 CreateDirectory()와 같은 GUID 생성 함수인 GetTempPath()를 사용하고 싶습니다.

GUID는 고유성이 높도록 설계되어 있으며, GUID와 같은 형식의 디렉토리를 수동으로 작성할 가능성도 매우 낮습니다(또한 작성하면 Create Directory()는 그 존재를 나타내는 데 실패합니다).

저는 몇 가지 답을 사용하고 구현했습니다.GetTmpDirectory이 방법을 사용합니다.

public string GetTmpDirectory()
{
    string tmpDirectory;

    do
    {
        tmpDirectory = Path.Combine(Path.GetTempPath(), Path.GetFileNameWithoutExtension(Path.GetRandomFileName()));
    } while (Directory.Exists(tmpDirectory));

    Directory.CreateDirectory(tmpDirectory);
    return tmpDirectory;
}

@Chris. 나도 임시 디렉토리가 이미 존재할 수 있다는 리모트 리스크에 사로잡혀 있었다.무작위적이고 암호적으로 강력한 논의도 나를 완전히 만족시키지 못한다.

저의 접근방식은 OS가 두 가지 모두 성공하기 위해서는 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/inch 코드의 "비용/리스크"가 가치가 있는지 여부를 결정할 수 있습니다.대부분은 그렇지 않다고 말하겠지만, 적어도 이제 당신은 선택의 여지가 있다.

CreateParentFolder()는 학생에게 연습으로 남습니다.디렉토리를 사용합니다.Create Directory()를 선택합니다.디렉토리는 루트에 있을 때는 늘이 되므로 디렉토리의 부모를 취득할 때 주의하십시오.

주로 사용하는 것은 다음과 같습니다.

    /// <summary>
    /// Creates the unique temporary directory.
    /// </summary>
    /// <returns>
    /// Directory path.
    /// </returns>
    public string CreateUniqueTempDirectory()
    {
        var uniqueTempDir = Path.GetFullPath(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()));
        Directory.CreateDirectory(uniqueTempDir);
        return uniqueTempDir;
    }

이 디렉토리명이 temp 패스에 존재하지 않는 것을 확실히 하려면 , 이 일의의 디렉토리명이 존재하는지를 확인해, 실제로 존재하는 경우는 다른 디렉토리명을 작성할 필요가 있습니다.

단, 이 GUID 기반의 실장만으로 충분합니다.저는 이 경우 어떤 문제에도 경험이 없습니다.일부 MS 애플리케이션에서는 GUID 기반 임시 디렉토리도 사용합니다.

다음은 임시 디렉토리 이름의 충돌 문제를 해결하기 위한 다소 더 강력한 방법입니다.이 방법은 완벽한 방법은 아니지만 폴더 경로 충돌 가능성을 크게 줄입니다.

임시 디렉토리 이름에 이러한 정보를 표시하는 것은 바람직하지 않을 수 있지만, 다른 프로세스 또는 어셈블리 관련 정보를 디렉토리 이름에 추가하여 충돌 가능성을 더 낮출 수 있습니다.또한 시간 관련 필드가 결합된 순서를 혼합하여 폴더 이름을 더 랜덤하게 표시할 수도 있습니다.디버깅 중에 모든 것을 쉽게 찾을 수 있기 때문에 개인적으로는 그렇게 두는 것을 선호합니다.

string randomlyGeneratedFolderNamePart = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());

string timeRelatedFolderNamePart = DateTime.Now.Year.ToString()
                                 + DateTime.Now.Month.ToString()
                                 + DateTime.Now.Day.ToString()
                                 + DateTime.Now.Hour.ToString()
                                 + DateTime.Now.Minute.ToString()
                                 + DateTime.Now.Second.ToString()
                                 + DateTime.Now.Millisecond.ToString();

string processRelatedFolderNamePart = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();

string temporaryDirectoryName = Path.Combine( Path.GetTempPath()
                                            , timeRelatedFolderNamePart 
                                            + processRelatedFolderNamePart 
                                            + randomlyGeneratedFolderNamePart);

위에서 설명한 바와 같이 Path.GetTempPath()는 이를 위한 하나의 방법입니다.환경에 전화할 수도 있습니다.사용자가 TEMP 환경변수를 설정하고 있는 경우 GetEnvironmentVariable('TEMP').

temp 디렉토리를 애플리케이션의 데이터를 유지하는 수단으로 사용할 예정이라면 구성/상태 등의 저장소로 Isolated Storage를 사용하는 것이 좋습니다.

.NET 7 이후

var tempFolder = Directory.CreateTempSubdirectory().FullName;

프레픽스를 추가하는 경우:

var tempFolder = Directory.CreateTempSubdirectory("prefix_").FullName;

GetTempPath가 올바른 방법입니다.이 메서드에 대한 당신의 우려는 잘 모르겠습니다.그런 다음 Create Directory를 사용하여 만들 수 있습니다.

언급URL : https://stackoverflow.com/questions/278439/creating-a-temporary-directory-in-windows

반응형