PowerShell 随机文件生成器太慢

PowerShell random file generator too slow

尝试使用此 PowerShell 脚本在 Windows 中生成随机文件:

param([string]$path = "C:\temp", [int]$size = "1024", [long]$number= "1000")
Write-Host "Path: $path"
Write-Host "Size of file: $size"
Write-Host "Number of files: $number"

Write-Host "Started at:"
Get-Date -Format HH:mm:ss

md -Force $path |out-null

$script:StartTime = $(Get-Date)
for($i=0; $i -le $number - 1 ; $i++){
    [Byte[]]$out=@(); 0..($size-1) | %{$out += Get-Random -Minimum 0 -Maximum 255};
    [System.IO.File]::WriteAll("$path$i.bin",$out)
    if (-Not ($i % 100) -and ($i -ne 0 )) {
        Write-Host "$i were created"
        $elapsedTime = $(Get-Date) - $script:StartTime
        $script:StartTime = $(Get-Date)
        Write-Host "$elapsedTime"
    }
}

当我想将文件大小从 1KB 增加到 1MB 时,即使是一个文件也需要很长时间,但我需要数千个文件。有没有办法解决这个瓶颈?

已解决dd for windows

#default values

param([string]$path = "C:\temp", [int]$size = "1048576", [long]$number= "10000")
Write-Host "Path: $path"
Write-Host "Size of file: $size"
Write-Host "Number of files: $number"

##dd.exe should be in same dir
$path_to_dd = Get-Location 

Write-Host "Started at:"
Get-Date -Format HH:mm:ss

md -Force $path |out-null

$script:StartTime = $(Get-Date)

for($i=0; $i -le $number - 1 ; $i++){
    #genarate files
    (& $path_to_dd\dd.exe if=/dev/random of=$path$i.bin bs=$size count=1) 2>&1 | Out-Null
    #periodical report to stdout with timestamp every 1k files
    if (-Not ($i % 1000) -and ($i -ne 0 )) {
        Write-Host "$i were created"
        $elapsedTime = $(Get-Date) - $script:StartTime
        $script:StartTime = $(Get-Date)
        Write-Host "$elapsedTime"
    }
}

Write-Host "Finished at:"
Get-Date -Format HH:mm:ss
Function New-RandomFile {
    Param(
        $Path = '.', 
        $FileSize = 1kb, 
        $FileName = [guid]::NewGuid().Guid + '.txt'
        ) 
    (1..($FileSize/128)).foreach({-join ([guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid -Replace "-").SubString(1, 126) }) | set-content "$Path$FileName"
}

生成一个 1mb 的文件用了 491 毫秒。 运行:

New-RandomFile -FileSize 1mb

更新:

我已经更新了我的函数以使用 ScriptBlock,因此您可以用任何您想要的方式替换 'NewGuid()' 方法。

在这种情况下,我制作了 1kb 的块,因为我知道我永远不会创建更小的文件。这大大提高了我的功能的速度!

Set-Content 在末尾强制换行,这就是每次写入文件时需要删除 2 个字符的原因。我已将其替换为 [io.file]::WriteAllText()。

Function New-RandomFile_1kChunks {
    Param(
        $Path = (Resolve-Path '.').Path, 
        $FileSize = 1kb, 
        $FileName = [guid]::NewGuid().Guid + '.txt'
        ) 

    $Chunk = { [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid +
               [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid +
               [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid +
               [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid +
               [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid +
               [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid +
               [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid +
               [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid -Replace "-" }

    $Chunks = [math]::Ceiling($FileSize/1kb)

    [io.file]::WriteAllText("$Path$FileName","$(-Join (1..($Chunks)).foreach({ $Chunk.Invoke() }))")

    Write-Warning "New-RandomFile: $Path$FileName"

}

如果你不关心所有块都是随机的,你可以简单地调用()一次1kb块的生成..这大大提高了速度,但不会使整个文件随机。

Function New-RandomFile_Fast {
    Param(
        $Path = (Resolve-Path '.').Path, 
        $FileSize = 1kb, 
        $FileName = [guid]::NewGuid().Guid + '.txt'
        ) 

    $Chunk = { [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid +
               [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid +
               [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid +
               [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid +
               [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid +
               [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid +
               [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid +
               [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid + [guid]::NewGuid().Guid -Replace "-" }
    $Chunks = [math]::Ceiling($FileSize/1kb)
    $ChunkString = $Chunk.Invoke()

    [io.file]::WriteAllText("$Path$FileName","$(-Join (1..($Chunks)).foreach({ $ChunkString }))")

    Write-Warning "New-RandomFile: $Path$FileName"

}

测量命令所有这些更改以生成一个 10mb 文件:

执行 New-RandomFile:35.7688241 秒。

执行 New-RandomFile_1kChunks:25.1463777 秒。

执行 New-RandomFile_Fast:1.1626236 秒。