PowerShell将文件移动到Amazon S3

3
我有以下 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}

}

http://meta.stackexchange.com/questions/22754/sscce-how-to-provide-examples-for-programming-questions - user189198
1个回答

6
从描述来看,您上传的较大文件触发了分段上传。根据Write-S3Object文档
如果您正在上传较大的文件,Write-S3Object cmdlet将使用分段上传来完成请求。如果分段上传被中断,Write-S3Object cmdlet将尝试中止分段上传。
不幸的是,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 内容以满足需求。我为了让你能够观察到它的工作原理而添加了 sleep 语句 - 随意更改 / 删除它们。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接