我正在使用这个简单的函数下载文件:
function DownloadFile([string]$url, [string]$file)
{
$clnt = new-object System.Net.WebClient
Write-Host "Downloading from $url to $file "
$clnt.DownloadFile($url, $file)
}
它工作正常,但我使用的脚本调用它可以多次调用,目前可能意味着多次下载文件。
如果文件在本地不存在或者服务器版本较新(例如服务器上的LastModifiedDate大于本地LastModifiedDate),我如何修改该功能才能下载?
修改 这是我到目前为止所做的,似乎有效,但不希望有2次调用服务器。
function DownloadFile([string]$url, [string]$file)
{
$downloadRequired = $true
if ((test-path $file))
{
$localModified = (Get-Item $file).LastWriteTime
$webRequest = [System.Net.HttpWebRequest]::Create($url);
$webRequest.Method = "HEAD";
$webResponse = $webRequest.GetResponse()
$remoteLastModified = ($webResponse.LastModified) -as [DateTime]
$webResponse.Close()
if ($remoteLastModified -gt $localModified)
{
Write-Host "$file is out of date"
}
else
{
$downloadRequired = $false
}
}
if ($downloadRequired)
{
$clnt = new-object System.Net.WebClient
Write-Host "Downloading from $url to $file"
$clnt.DownloadFile($url, $file)
}
else
{
Write-Host "$file is up to date."
}
}
答案 0 :(得分:7)
本周我一直在打这个,并想出了这个
# ----------------------------------------------------------------------------------------------
# download a file
# ----------------------------------------------------------------------------------------------
Function Download-File {
Param (
[Parameter(Mandatory=$True)] [System.Uri]$uri,
[Parameter(Mandatory=$True )] [string]$FilePath
)
#Make sure the destination directory exists
#System.IO.FileInfo works even if the file/dir doesn't exist, which is better then get-item which requires the file to exist
If (! ( Test-Path ([System.IO.FileInfo]$FilePath).DirectoryName ) ) { [void](New-Item ([System.IO.FileInfo]$FilePath).DirectoryName -force -type directory)}
#see if this file exists
if ( -not (Test-Path $FilePath) ) {
#use simple download
[void] (New-Object System.Net.WebClient).DownloadFile($uri.ToString(), $FilePath)
} else {
try {
#use HttpWebRequest to download file
$webRequest = [System.Net.HttpWebRequest]::Create($uri);
$webRequest.IfModifiedSince = ([System.IO.FileInfo]$FilePath).LastWriteTime
$webRequest.Method = "GET";
[System.Net.HttpWebResponse]$webResponse = $webRequest.GetResponse()
#Read HTTP result from the $webResponse
$stream = New-Object System.IO.StreamReader($webResponse.GetResponseStream())
#Save to file
$stream.ReadToEnd() | Set-Content -Path $FilePath -Force
} catch [System.Net.WebException] {
#Check for a 304
if ($_.Exception.Response.StatusCode -eq [System.Net.HttpStatusCode]::NotModified) {
Write-Host " $FilePath not modified, not downloading..."
} else {
#Unexpected error
$Status = $_.Exception.Response.StatusCode
$msg = $_.Exception
Write-Host " Error dowloading $FilePath, Status code: $Status - $msg"
}
}
}
}
答案 1 :(得分:1)
# If the local directory exists and it gets a response from the url,
# it checks the last modified date of the remote file. If the file
# already exists it compares the date of the file to the file from
# the url. If either the file doesn't exists or has a newer date, it
# downloads the file and modifies the file's date to match.
function download( $url, $dir, $file ) {
if( Test-Path $dir -Ea 0 ) {
$web = try { [System.Net.WebRequest]::Create("$url/$file").GetResponse() } catch [Net.WebException] {}
if( $web.LastModified ) {
$download = 0
if(-Not(Test-Path "$dir\$file" -Ea 0)) { $download = 1 }
elseif((gi "$dir\$file").LastWriteTime -ne $web.LastModified) { $download = 1 }
if( $download ) {
Invoke-WebRequest "$url/$file" -OutFile "$dir\$file" | Wait-Process
(gi "$dir\$file").LastWriteTime = $web.LastModified
}
$web.Close()
}
}
}
download "https://website.com" "$env:systemdrive" "file.txt"
答案 2 :(得分:0)
最后修改的是HTTP响应标头。
试试这个:
$clnt.OpenRead($Url).Close();
$UrlLastModified = $clnt.ResponseHeaders["Last-Modified"];
如果它比您文件上的日期新,那么您的文件已经过时了。
远程服务器不必回复准确的日期或文件的实际上次修改日期,但很多人会这样做。
GetWebResponse()
可能是更好的方法(或更正确的方式)。之后立即使用OpenRead()
然后Close()
会影响我的敏感度,但我可能会发疯。我主要从事数据库工作。