Powershell - 为什么使用Invoke-WebRequest比浏览器下载慢得多?

Llo*_*nks 39 powershell amazon-s3 amazon-ec2 powershell-3.0

我使用Powershell的Invoke-WebRequest方法将文件从Amazon S3下载到我的Windows EC2实例.

如果我使用Chrome下载文件,我可以在5秒内下载200 MB文件.PowerShell使用相同的下载Invoke-WebRequest最多需要5分钟.

为什么使用Invoke-WebRequest速度较慢,有没有办法在PowerShell脚本中全速下载?

Tin*_*rus 53

如果不切换Invoke-WebRequest,关闭进度条就可以了.我找到了这个帖子的答案:https://github.com/PowerShell/PowerShell/issues/2138(jasongin于2016年10月3日评论)

$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest <params>
Run Code Online (Sandbox Code Playgroud)

对于localhost上的5MB文件,下载时间从30秒到250毫秒.

请注意,要在活动shell中获取进度条,您需要调用$ProgressPreference = 'Continue'.

  • 关于如何不实现进度条的课程。 (3认同)
  • Windows 一点也没有改变。 (3认同)
  • 这对我们来说也是一个巨大的差异(对于10-30MB文件,几十秒到不到一秒钟) - 我总是怀疑是进度显示减慢了速度,但不知道如何阻止它这样做. (2认同)
  • 对于100MB的文件,这会将时间从10分钟减少到2秒。我希望开发人员能更多地考虑其软件的体系结构。 (2认同)
  • 对于 280MB 的文件,时间从 33 分钟缩短到 28 秒。疯狂的! (2认同)
  • 似乎进度条在每个字节之后都会更新,这简直是疯狂。 (2认同)
  • 无法相信“-ProgressPreference”不是“Invoke-WebRequest”的参数 (2认同)
  • 2023 年仍然是一个主要问题。请注意,这还有[额外的好处](/sf/ask/5261764511/)。 (2认同)

Llo*_*nks 27

我在用

Invoke-WebRequest $video_url -OutFile $local_video_url
Run Code Online (Sandbox Code Playgroud)

我改变了以上内容

$wc = New-Object net.webclient
$wc.Downloadfile($video_url, $local_video_url)
Run Code Online (Sandbox Code Playgroud)

这将下载速度恢复到我在浏览器中看到的速度.

  • 所以我只是运行`wc.downloadFile(ibm-s3-url,“ ./test.tar.gz”)`,它做了一些事情,大概是下载了该文件,但是没有把它放在我的工作目录中。它可能去了哪里? (2认同)

小智 10

$ProgressPreference = 'SilentlyContinue' 对于 450 M. 壮观的文件,我将其从 52 分钟缩短到 14 秒。

  • 这是 PowerShell 的内置[首选项变量](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-5.1#progresspreference),并控制某些操作是否显示进度条,例如通过“Invoke-WebRequest”下载文件。此处提高性能的原因是因为“Invoke-WebRequest”(和“Invoke-RestMethod”)过于频繁地计算下载的字节(*每个字节*我相信),因此 cmdlet 实际上会减慢,因为它会计算字节数已被处理。 (2认同)

Blu*_*Sky 9

单行下载文件到临时目录:

(New-Object Net.WebClient).DownloadFile("https://www.google.com", "$env:temp\index.html")
Run Code Online (Sandbox Code Playgroud)

  • Lloyd 问:“有没有办法在 PowerShell 脚本中全速下载?” 这个答案是一种简单的方法。下载到临时目录是演示这一点的规范方法。 (2认同)
  • 这实际上是一个很好的答案,由于 Invoke-WebRequest 跟踪其自身进度的方式,WebClient.DownloadFile 比 Invoke-WebRequest 快得多 (2认同)
  • 绝对相关,这完全解决了OP的问题(和我的:)) (2认同)