PowerShell实现文件下载(类wget)

对Linux熟悉的读者可能会对Linux通过wget下载文件有印象,这个工具功能很强大,在.NET环境下提到下载文件大多数人熟悉的是通过System.Net.WebClient进行下载,这个程序集能实现下载的功能,但是有缺陷,如果碰上类似于.../scripts/?dl=417这类的下载链接将无法正确识别文件名,下载的文件通常会被命名为dl=417这样古怪的名字,其实对应的文件名是在访问这个链接返回结果的HTTP头中包含的。事实上微软也提供了避免这些缺陷的程序集System.Net.HttpWebRequestHttpWebResponse,本文将会使用这两个程序集来实现PowerShell版wget的功能。

代码不怎么复杂,基本上就是创建HttpWebRequest对象,设定UserAgent和CookieContainer以免在遇到设置防盗链的服务器出现无法下载的情况。然后通过HttpWebRequest对象的GetResponse()方法从http头中获取目标文件的大小以及文件名,以便能在下载到文件时提示当前下载进度,在下载完文件后,列出当前目录下对应的文件。代码不复杂,有任何疑问的读者可以留言给我,进行交流,下面上代码:

        =====文件名:Get-WebFile.ps1=====
 Get-WebFile {
<
   Downloads a file or page from the web
.Example
  Get-WebFile http://mirrors.cnnic.cn/apache/couchdb/binary/win/1.4.0/setup-couchdb-1.4.0_R16B01.exe
  Downloads the latest version of this file to the current directory


[CmdletBinding(DefaultParameterSetName=)]
   (

      [Parameter(Mandatory=$true,Position=0)]
      [System.Uri][Alias()]$Uri 
   ,

      []$FileName
   ,

      []$Unblocked
   ,


      []$Passthru
   ,

      []$Quiet
   ,

      []$SessionVariableName
   ,

      []$UserAgent =       
   )

    "Downloading 
   $EAP,$ErrorActionPreference = $ErrorActionPreference, 
   $request = [System.Net.HttpWebRequest]::Create($Uri);
   $ErrorActionPreference = $EAP   
   $request.UserAgent = $(
           $UserAgent, 
         $(($Host.Version){$Host.Version}{}),
         [Environment]::Version,
         [Environment]::OSVersion.ToString().Replace(, )
      )

   $Cookies =  System.Net.CookieContainer
   ($SessionVariableName) {
      $Cookies =  $SessionVariableName -Scope 1 
   }
   $request.CookieContainer = $Cookies
   ($SessionVariableName) {
       $SessionVariableName -Scope 1 -Value $Cookies
   }

    {
      $res = $request.GetResponse();
   }  [System.Net.WebException] { 
       $_.Exception -Category ResourceUnavailable
      
   }  {
       $_.Exception -Category NotImplemented
      
   }

   (( variable:res)  $res.StatusCode  200) {
      ($fileName  !( $fileName)) {
         $fileName =  ( ( -PSProvider )) $fileName
      }
      ((!$Passthru  !$fileName)  ($fileName  ( -PathType  $fileName)))
      {
         []$fileName = ([regex]'&
         $fileName = $fileName.trim("&

         $ofs = 
         $fileName = [Regex]::Replace($fileName, , )
         $ofs = 

         (!$fileName) {
            $fileName = $res.ResponseUri.Segments[-1]
            $fileName = $fileName.trim()
            (!$fileName) { 
               $fileName =  
            }
            $fileName = $fileName.trim()
            (!([IO.FileInfo]$fileName).Extension) {
               $fileName = $fileName +  + $res.ContentType.Split()[0].Split()[1]
            }
         }
         $fileName =  ( ( -PSProvider )) $fileName
      }
      ($Passthru) {
         $encoding = [System.Text.Encoding]::GetEncoding( $res.CharacterSet )
         []$output = 
      }

      []$goal = $res.ContentLength
      $reader = $res.GetResponseStream()
      ($fileName) {
          {
            $writer =  System.IO.FileStream $fileName, 
         }  {
             $_.Exception -Category WriteError
            
         }
      }
      [byte[]]$buffer =  byte[] 4096
      []$total = []$count = 0
      
      {
         $count = $reader.Read($buffer, 0, $buffer.Length);
         ($fileName) {
            $writer.($buffer, 0, $count);
         } 
         ($Passthru){
            $output += $encoding.GetString($buffer,0,$count)
         } (!$quiet) {
            $total += $count
            ($goal  0) {
                  -id 0 -percentComplete (($total/$goal)*100)
            }  {
                  -id 0
            }
         }
      }  ($count  0)

      $reader.Close()
      ($fileName) {
         $writer.Flush()
         $writer.Close()
      }
      ($Passthru){
         $output
      }
   }
   ( variable:res) { $res.Close(); }
   ($fileName) {
       $fileName
   }
}

调用方法,如下:

Get-WebFile http://mirrors.cnnic.cn/apache/couchdb/binary/win/1.4.0/setup-couchdb-1.4.0_R16B01.exe

这里下载couchdb的最新windows安装包。

执行效果如下图所示:

PowerShell实现文件下载(类wget)

能够看到在下载文件的过程中会显示当前已下载数和总的文件大小,并且有进度条显示当前下载的进度,跟wget看起来是有些神似了。下载完毕后会显示已经下载文件的情况。

PowerShell实现文件下载(类wget)

作者: 付海军
出处:http://fuhj02.cnblogs.com
版权:本文版权归作者和博客园共有
转载:欢迎转载,为了保存作者的创作热情,请按要求【转载】,谢谢
要求:未经作者同意,必须保留此段声明;必须在文章中给出原文连接且保证内容完整!否则必究法律责任!
个人网站: http://www.fuhaijun.com/