对Linux熟悉的读者可能会对Linux通过wget下载文件有印象,这个工具功能很强大,在.NET环境下提到下载文件大多数人熟悉的是通过System.Net.WebClient进行下载,这个程序集能实现下载的功能,但是有缺陷,如果碰上类似于.../scripts/?dl=417这类的下载链接将无法正确识别文件名,下载的文件通常会被命名为dl=417这样古怪的名字,其实对应的文件名是在访问这个链接返回结果的HTTP头中包含的。事实上微软也提供了避免这些缺陷的程序集System.Net.HttpWebRequest 和 HttpWebResponse,本文将会使用这两个程序集来实现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安装包。
执行效果如下图所示:
能够看到在下载文件的过程中会显示当前已下载数和总的文件大小,并且有进度条显示当前下载的进度,跟wget看起来是有些神似了。下载完毕后会显示已经下载文件的情况。
作者: 付海军
出处:http://fuhj02.cnblogs.com
版权:本文版权归作者和博客园共有
转载:欢迎转载,为了保存作者的创作热情,请按要求【转载】,谢谢
要求:未经作者同意,必须保留此段声明;必须在文章中给出原文连接且保证内容完整!否则必究法律责任!
个人网站: http://www.fuhaijun.com/