Ответ 1

Я думаю, что это можно сделать без цикла с помощью GUID для имени каталога:

function New-TemporaryDirectory {
    $parent = [System.IO.Path]::GetTempPath()
    [string] $name = [System.Guid]::NewGuid()
    New-Item -ItemType Directory -Path (Join-Path $parent $name)
}

Исходная попытка с GetRandomFileName

Здесь мой порт это решение С#:

function New-TemporaryDirectory {
    $parent = [System.IO.Path]::GetTempPath()
    $name = [System.IO.Path]::GetRandomFileName()
    New-Item -ItemType Directory -Path (Join-Path $parent $name)
}

Анализ возможности столкновения

Насколько вероятно, что GetRandomFileName вернет имя, которое уже существует в папке temp?

  • Имена файлов возвращаются в форме XXXXXXXX.XXX, где X может быть строчной буквой или цифрой.
  • Это дает нам комбинации 36 ^ 11, которые в битах составляют около 2 ^ 56
  • Вызывая парадокс дня рождения, мы ожидаем столкновения, когда мы получим около 2 ^ 28 элементов в папке, что составляет около 360 млн
  • NTFS поддерживает около 2 ^ 32 элементов в папке, поэтому можно получить столкновение с помощью GetRandomFileName

NewGuid с другой стороны может быть одним из 2 ^ 122 возможностей, делая коллизии практически невозможными.

Ответ 2

Я также люблю однострочники, и я прошу понизить здесь. Все, что я прошу, это чтобы вы выразили мои смутные негативные чувства по этому поводу словами.

New-TemporaryFile | %{ rm $_; mkdir $_ }

В зависимости от типа пуриста, вы можете сделать %{ mkdir $_-d }, оставляя заполнитель, чтобы избежать коллизий.

И разумно стоять на Join-Path $env:TEMP $(New-Guid) | %{ mkdir $_ } Join-Path $env:TEMP $(New-Guid) | %{ mkdir $_ } также.

Ответ 3

Здесь моя попытка:

function New-TemporaryDirectory {
    $path = Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName())

    #if/while path already exists, generate a new path
    while(Test-Path $path)) {
        $path = Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName())
    }

    #create directory with generated path
    New-Item -ItemType Directory -Path $path
}

Ответ 4

У .NET было [System.IO.Path]::GetTempFileName() довольно долгое время; вы можете использовать это для создания файла (и захвата имени), а затем создать папку с тем же именем после удаления файла.

$tempfile = [System.IO.Path]::GetTempFileName();
remove-item $tempfile;
new-item -type directory -path $tempfile;

Ответ 5

Мне нравится, если возможно, один лайнер. @alroc.NET также имеет [System.Guid]::NewGuid()

$temp = [System.Guid]::NewGuid();new-item -type directory -Path d:\$temp

Directory: D:\


Mode                LastWriteTime     Length Name                                                                                                                        
----                -------------     ------ ----                                                                                                                        
d----          1/2/2016  11:47 AM            9f4ef43a-a72a-4d54-9ba4-87a926906948  

Ответ 6

Развернувшись от Майкла Кропата, ответьте: fooobar.com/info/624893/...

Function New-TemporaryDirectory {
  $tempDirectoryBase = [System.IO.Path]::GetTempPath();
  $newTempDirPath = [String]::Empty;
  Do {
    [string] $name = [System.Guid]::NewGuid();
    $newTempDirPath = (Join-Path $tempDirectoryBase $name);
  } While (Test-Path $newTempDirPath);

  New-Item -ItemType Directory -Path $newTempDirPath;
  Return $newTempDirPath;
}

Это должно устранить любые проблемы с конфликтами.