代码之家  ›  专栏  ›  技术社区  ›  godofgrunts

PowerShell:System.Net.WebClient。DownloadFile不会下载从ListDirectory收集的文件

  •  2
  • godofgrunts  · 技术社区  · 8 年前

    我正在尝试从FTP服务器下载一些zip文件。FTP服务器的结构如下

    ftp://ftp.example.com
    |
     -> /Download
        | 
         -> file1.zip, file2.zip, file3.zip etc
    

    我已将所有文件放入一个名为 $ftpFiles

    foreach ($zip in $ftpFiles)
    {
        $LocalFile = "C:\Temp\$zip"
        $RemoteFile = "$site/$zip"
        $ftp = New-Object System.Net.WebClient
        $ftp.Credentials = new-object System.Net.NetworkCredential($Username, $realPassword)
        $uri = New-Object System.Uri("$RemoteFile")
        $ftp.DownloadFile($uri, $LocalFile)
        Write-Host "$zip download complete"
    }
    

    问题是 $ftp.DownloadFile 无法与我的 $LocalFile 变量但是,如果我手动输入 $本地文件 信息。

    例如

    $ftp.DownloadFile($uri, "C:\temp\file1.zip")
    

    效果不错,但

    $ftp.DownloadFile($uri, $LocalFile)
    

    给我以下错误

    Exception calling "DownloadFile" with "2" argument(s): "An exception occurred during a WebClient request."
    At line:1 char:34
     +                 $ftp.DownloadFile <<<< ($uri, $LocalFile)
     + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
     + FullyQualifiedErrorId : DotNetMethodException
    

    为了调试目的,我一直在做

    write-host $LocalFile
    

    它将正确返回为

    C:\Temp\file1.zip
    

    正如我所料。

    我只能假设 DownloadFile 不喜欢嵌套变量,正在将其读取为 C:\Temp\$zip 我不知道该怎么去修理它。

    编辑:评论希望了解 $files 数组已生成

    $site = $ftpbase + $dir
    
    $ftp = [System.Net.FtpWebRequest]::Create("$site")
    $ftp.Method = [System.Net.WebRequestMethods+FTP]::ListDirectory #Details
    $ftp.Credentials = new-object System.Net.NetworkCredential($Username, $realPassword)
    
    $response = $ftp.getresponse() 
    $stream = $response.getresponsestream() 
    
    $buffer = new-object System.Byte[] 1024 
    $encoding = new-object System.Text.AsciiEncoding 
    
    $outputBuffer = "" 
    $foundMore = $false 
    
    ## Read all the data available from the stream, writing it to the 
    ## output buffer when done. 
    do 
    {
    
        ## Allow data to buffer for a bit 
        start-sleep -Seconds 2 
    
        ## Read what data is available 
        $foundmore = $false 
        $stream.ReadTimeout = 1000
    
        do 
        { 
            try 
            { 
                $read = $stream.Read($buffer, 0, 1024) 
    
                if($read -gt 0) 
                { 
                    $foundmore = $true 
                    $outputBuffer += ($encoding.GetString($buffer, 0, $read))
    
                } 
            } catch { $foundMore = $false; $read = 0 } 
        } while($read -gt 0) 
    } 
    while($foundmore)
    
    $files = $outputBuffer -split ("\n")
    
    1 回复  |  直到 8 年前
        1
  •  3
  •   Martin Prikryl    8 年前

    的输出 ListDirectory 为ASCII模式,其中行由 \r\n 。您将输出拆分为 \n 只有,所以 \r 保存在文件名中。

    因此,下载失败,因为文件 file1.zip\r 不存在。

    打印时 文件1.zip\r ,您不会看到 \r(右) .