1. 程式人生 > >PowerShell實現檔案下載(類wget)

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=====
function Get-WebFile {
<# Author:fuhj(powershell#live.cn ,http://fuhaijun.com) 
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="NoCredentials")] param( # The URL of the file/page to download
[Parameter(Mandatory=$true,Position=0)] [System.Uri][Alias("Url")]$Uri # = (Read-Host "The URL to download") , # A Path to save the downloaded content. [string]$FileName , # Leave the file unblocked instead of blocked [Switch]$Unblocked , # Rather than saving the downloaded content to a file, output it. # This is for text documents like web pages and rss feeds, and allows you to avoid temporarily caching the text in a file. [switch]$Passthru , # Supresses the Write-Progress during download [switch]$Quiet , # The name of a variable to store the session (cookies) in [String]$SessionVariableName , # Text to include at the front of the UserAgent string [string]$UserAgent = "PowerShellWget/$(1.0)" ) Write-Verbose "Downloading &#39;$Uri'" $EAP,$ErrorActionPreference = $ErrorActionPreference, "Stop" $request = [System.Net.HttpWebRequest]::Create($Uri); $ErrorActionPreference = $EAP $request.UserAgent = $( "{0} (PowerShell {1}; .NET CLR {2}; {3}; http://fuhaijun.com)" -f $UserAgent, $(if($Host.Version){$Host.Version}else{"1.0"}), [Environment]::Version, [Environment]::OSVersion.ToString().Replace("Microsoft Windows ", "Win") ) $Cookies = New-Object System.Net.CookieContainer if($SessionVariableName) { $Cookies = Get-Variable $SessionVariableName -Scope 1 } $request.CookieContainer = $Cookies if($SessionVariableName) { Set-Variable $SessionVariableName -Scope 1 -Value $Cookies } try { $res = $request.GetResponse(); } catch [System.Net.WebException] { Write-Error $_.Exception -Category ResourceUnavailable return } catch { Write-Error $_.Exception -Category NotImplemented return } if((Test-Path variable:res) -and $res.StatusCode -eq 200) { if($fileName -and !(Split-Path $fileName)) { $fileName = Join-Path (Convert-Path (Get-Location -PSProvider "FileSystem")) $fileName } elseif((!$Passthru -and !$fileName) -or ($fileName -and (Test-Path -PathType "Container" $fileName))) { [string]$fileName = ([regex]'&#40;?i)filename=(.*)$').Match( $res.Headers["Content-Disposition"] ).Groups[1].Value $fileName = $fileName.trim("&#92;/""'") $ofs = "" $fileName = [Regex]::Replace($fileName, "[$([Regex]::Escape(""$([System.IO.Path]::GetInvalidPathChars())$([IO.Path]::AltDirectorySeparatorChar)$([IO.Path]::DirectorySeparatorChar)""))]", "_") $ofs = " " if(!$fileName) { $fileName = $res.ResponseUri.Segments[-1] $fileName = $fileName.trim("\/") if(!$fileName) { $fileName = Read-Host "Please provide a file name" } $fileName = $fileName.trim("\/") if(!([IO.FileInfo]$fileName).Extension) { $fileName = $fileName + "." + $res.ContentType.Split(";")[0].Split("/")[1] } } $fileName = Join-Path (Convert-Path (Get-Location -PSProvider "FileSystem")) $fileName } if($Passthru) { $encoding = [System.Text.Encoding]::GetEncoding( $res.CharacterSet ) [string]$output = "" } [int]$goal = $res.ContentLength $reader = $res.GetResponseStream() if($fileName) { try { $writer = new-object System.IO.FileStream $fileName, "Create" } catch { Write-Error $_.Exception -Category WriteError return } } [byte[]]$buffer = new-object byte[] 4096 [int]$total = [int]$count = 0 do { $count = $reader.Read($buffer, 0, $buffer.Length); if($fileName) { $writer.Write($buffer, 0, $count); } if($Passthru){ $output += $encoding.GetString($buffer,0,$count) } elseif(!$quiet) { $total += $count if($goal -gt 0) { Write-Progress "Downloading $Uri" "Saving $total of $goal" -id 0 -percentComplete (($total/$goal)*100) } else { Write-Progress "Downloading $Uri" "Saving $total bytes..." -id 0 } } } while ($count -gt 0) $reader.Close() if($fileName) { $writer.Flush() $writer.Close() } if($Passthru){ $output } } if(Test-Path variable:res) { $res.Close(); } if($fileName) { ls $fileName } }

呼叫方法,如下:

這裡下載couchdb的最新windows安裝包。

執行效果如下圖所示:

image

能夠看到在下載檔案的過程中會顯示當前已下載數和總的檔案大小,並且有進度條顯示當前下載的進度,跟wget看起來是有些神似了。下載完畢後會顯示已經下載檔案的情況。

image

作者: 付海軍
出處:http://fuhj02.cnblogs.com
版權:本文版權歸作者和部落格園共有
轉載:歡迎轉載,為了儲存作者的創作熱情,請按要求【轉載】,謝謝
要求:未經作者同意,必須保留此段宣告;必須在文章中給出原文連線且保證內容完整!否則必究法律責任!
個人網站: http://www.fuhaijun.com/

相關推薦

PowerShell實現檔案下載(wget)

對Linux熟悉的讀者可能會對Linux通過wget下載檔案有印象,這個工具功能很強大,在.NET環境下提到下載檔案大多數人熟悉的是通過System.Net.WebClient進行下載,這個程式集能實現下載的功能,但是有缺陷,如果碰上類似於.../scripts/?dl=417這類的下載連結將無法正確識別檔名

Spring 實現檔案下載功能

方式1: public void download(HttpServletResponse response,@RequestParam(value="params") String params) throws IOException, DocumentException{ response

JQuery 實現檔案下載

GET方式 window.location.href = url; POST方式 var url = "下載介面地址"; // 構造隱藏的form表單 var $form = $("<form id='download' class='hidden' method='po

Servlet實現檔案下載

在瀏覽網站的時候很多涉及到檔案下載的情況,在初學JavaWeb的時候我們如何使用Servlet來實現檔案下載呢? 在學習此之前,我們要知道兩個重要的概念。request和response。請求和相應。 請求:請求頭、請求行、請求體。 相應:相應頭、相應行、相應體。 大家可以上網找一下

java web實現檔案下載

javaweb實現檔案下載 實現檔案下載 解決下載檔名帶有中文亂碼問題 效果圖 實現思路 根據請求連接獲取檔名和檔案型別,設定響應頭,獲取輸入流和輸出流 核心程式碼 public void doGet(HttpServletR

mvc 在彈出框中實現檔案下載

var myParent = parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; FileDown = function (fileName, realFileName) { $

前端實現檔案下載和拖拽上傳

蘇格團隊 作者:WDZ 交流QQ群:855833773 歡迎加入我們的團隊,微信聯絡方式:foreverpx_cjl 筆者在業務中碰到了需要下載示例和拖拽上傳並實現進度條的功能,針對過程中遇到的問題,筆者進行了相應的總結。 需求 頁面中增加下載示例按鈕

Java多執行緒使用執行緒池實現檔案下載

多執行緒下載原理: 1、基本思路是將檔案分段切割、分段傳輸、分段儲存。 2、分段切割用到HttpUrlConnection物件的setRequestProperty(“Range”, “bytes=” + start + “-” + end)方法。 3、分段傳輸用到HttpU

使用Servlet實現檔案下載

檔案下載 直接在html或jsp頁面寫入超連結 <!--點選後 瀏覽器可以解析的會自動開啟 不能解析度提示下載--> <a href="專案名/資源路徑">資源路</a> 編寫檔案下載功能 即不讓瀏覽器解析

Spring Boot實現檔案下載功能

我們只需要建立一個控制器(Controler)檔案,即Controller目錄下的File_Download.java,其完整目錄如下: @Controller public class File_Download { //實現Spring Boot 的檔案下載功能,對映網址為/download

C#實現檔案下載

/// <summary> /// 使用OutputStream.Write分塊下載檔案 /// </summary> /// <param name="filePath"></param>

宣告標頭檔案實現檔案的使用檔案(主檔案)放在一起的時候應該注意的問題

#include<iostream> using namespace std; class v { public:     void volume()     {         int vo;         cin>>length>>w

通過檔案url,實現檔案下載

通過url實現檔案下載 @Log("下載檔案") @ResponseBody @RequestMapping(value = "/download", method = RequestMethod.GET) public R Download(HttpServletResp

點選按鈕實現檔案下載

一、使用背景 一般來說,當我們上傳檔案之後,便會要提供檔案下載的入口。而其實檔案下載就是獲取檔案,並將檔案內容寫入到HTTP返回響應的過程。 二、前端實現方式 構造form表單提交 1、引入相關j

SpringMVC實現檔案下載功能(檔案匯出功能)

1.頁面程式碼 <a class="layui-btn" href="${pageContext.request.contextPath}/bAndWListManage/downloadWhiteListTmp.do" onclick="downloadTempla

Android Webview實現檔案下載功能

                    在做美圖欣賞Android應用的時候,其中有涉及到Android應用下載的功能,這個應用本身其實也比較簡單,就是通過WebView控制呼叫相應的WEB頁面進行展示。剛開始以為和普通的檔案下載實現,只需要一個連結,然後點選就可以實現下載了,可是放到手機上試的時候,點選下載

談一談url實現檔案下載

前幾天,一個關於下載的問題,把我困在原地蠻久,記錄一下。 說到標題,後臺返回一個url,前端瀏覽器開啟實現下載功能,直接想到的就是window.open(url) 來實現下載,但是這種方法 我個人認為一閃而過的白色頁面導致使用者體驗不是很好, so,就隨手寫寫。 1 wi

a標籤實現檔案下載

通過純前端技術實現檔案下載,使用a標籤的href屬性即可,如下: <a href="http://cdn.com/files/dowload?path=group1/M00/00/A7/wKgGSVvlJAMV9nkv5Vo853.pdf">download&l

java實現檔案下載的三種方式

public HttpServletResponse download(String path, HttpServletResponse response) {         try {          

javaweb實現檔案下載(包含.txt檔案等預設在瀏覽器中開啟的檔案

檔案下載  剛開始研究檔案下載是找有關js的方法,找了好多發現對於.txt、.xls等檔案在瀏覽器中還是開啟,或者就是跨域問題。後來通過查詢資料發現可以在後臺對http相應頭設定引數,而且實現起來也不復雜。現總結如下: 文章參考 《javaweb檔案下載》、《根據網路url 實現w