Power Shell перемещение файлов на Amazon S3

У меня есть приведенный ниже скрипт PowerShell, который перемещает файлы в мое хранилище amazon для меня, и все работает нормально для нескольких небольших файлов, однако при копировании больших файлов цикл for продолжает цикл и начинает их копирование до завершения других, и это не займет много времени. прежде чем у меня есть сотни файлов, все передающие сразу.

что я хочу, чтобы иметь возможность ограничить количество одновременных передач файлов, скажем, 5 или 10?

foreach ($line in $csv) {  

#--------------------Transfer files Put in a for each loop here---------------------------
$SourceFolder  =$line.destination
$sourceFile = $line.name

if(test-Path -path $SourceFolder){
    Write-S3Object -BucketName $BucketName  -Key $sourceFile  -File  $SourceFolder 
    #check fro missing files
        $S3GetRequest = New-Object Amazon.S3.Model.S3Object  #get-S3Object  -BucketName   $BucketName  -Key $sourceFile
        $S3GetRequest = get-S3Object  -BucketName $BucketName  -Key $sourceFile

        if($S3GetRequest -eq $null){
            Write-Error "ERROR: Amazon S3 get requrest failed. Script halted."
            $sourceFile + ",Transfer Error" |out-file $log_loc -append
    }
}else {$SourceFolder + ",Missing File Error" |out-file $log_loc -append}

}

1 ответ

Из описания звучит так, как будто ваши большие файлы запускают многочастную загрузку. Из документации Write-S3Object:

Если вы загружаете большие файлы, командлет Write-S3Object будет использовать многоэтапную загрузку для выполнения запроса. Если многокомпонентная загрузка прерывается, командлет Write-S3Object попытается прервать многокомпонентную загрузку.

К сожалению, у Write-S3Object нет собственного способа обработки вашего варианта использования. Тем не менее, Краткий обзор загрузки описывает поведение, которое мы можем использовать:

Многоэтапная загрузка состоит из трех этапов: вы начинаете загрузку, вы загружаете части объекта, а после того, как вы загрузили все части, вы завершаете многоэлементную загрузку. После получения полного запроса на многокомпонентную загрузку Amazon S3 создает объект из загруженных частей, и вы можете получить доступ к объекту так же, как и к любому другому объекту в вашем ведре.

Это заставляет меня подозревать, что мы можем пинговать наши объекты с Get-S3Object чтобы увидеть, существуют ли они еще. Если нет, то нам следует подождать загрузки большего количества файлов, пока они не загрузятся.

Ниже я создал скрипт, который будет делать это - он перебирает коллекцию файлов и собирает их имена по мере их загрузки. Когда вы превысите 5 загруженных файлов, скрипт проверит, существуют ли они, и продолжит работу, если они есть. В противном случае он продолжит проверять, существуют ли они.

$BucketName = "myS3Bucket"
$s3Directory = "C:\users\$env:username\documents\s3test"
$concurrentLimit = 5
$inProgressFiles = @()

foreach ($i in Get-ChildItem $s3Directory) 
{ 
  # Write the file to S3 and add the filename to a collection.
  Write-S3Object -BucketName $BucketName -Key $i.Name -File $i.FullName 
  $inProgressFiles += $i.Name

  # Wait to continue iterating through files if there are too many concurrent uploads
  while($inProgressFiles.Count -gt $concurrentLimit) 
  {
    Write-Host "Before: "$($inProgressFiles.Count)

    # Reassign the array by excluding files that have completed the upload to S3.
    $inProgressFiles = @($inProgressFiles | ? { @(get-s3object -BucketName $BucketName -Key $_).Count -eq 0 })

    Write-Host "After: "$($inProgressFiles.Count)

    Start-Sleep -s 1
  }

  Start-Sleep -s 1
}

Вы можете изменить это в соответствии со своими потребностями, изменив цикл foreach, чтобы использовать содержимое CSV. Я добавил заявления о сне, чтобы вы могли наблюдать за этим и видеть, как это работает - не стесняйтесь изменять / удалять их.

Другие вопросы по тегам