【问题标题】:How to resume FTP upload after connection is broken with PowerShell?如何在与 PowerShell 的连接断开后恢复 FTP 上传?
【发布时间】:2017-11-30 06:25:45
【问题描述】:

我有一个 PowerShell 脚本,我用它来将一个 7.3 Gb 的文件分块从美国传输到欧洲。该脚本工作正常,直到偶尔连接断开和传输停止。

我已经使用 try-catch 和重试计数器尝试了多个版本,因此如果连接失败,它会重试发送相同的块。

这通常有效,但问题是当连接断开时,如果连接设法将一半块发送到 FTP 位置,然后连接失败,它会再次尝试发送整个块,所以当它完成时我可以结束发送一个更大的文件。

这个较大的文件也是一个损坏/无效的文件,因为它只是一个比它应该有更多位和字节的堆。

我用来 FTP 文件的代码是:

# FTP connection details
$ftp_addr = "ftp://ftp.example.com/Backups/"
$user = "abc"
$pass = "1234"

$bufSize = 256mb

# some more irrelevant code here where I identify files to be FTP'ed etc.
# ......

# Initialize connection to FTP
$ftp = [System.Net.FtpWebRequest]::Create($destination_filename+".zip")
$ftp = [System.Net.FtpWebRequest]$ftp
$ftp.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile
$ftp.Credentials = new-object System.Net.NetworkCredential($user, $pass)

$ftp.Timeout = -1              #infinite timeout
$ftp.ReadWriteTimeout = -1     #infinite timeout

$ftp.UseBinary = $true
$ftp.UsePassive = $true

$requestStream = $ftp.GetRequestStream()
$fileStream = [System.IO.File]::OpenRead($backup_target_app_data)
$chunk = New-Object byte[] $bufSize

try {

    while( $bytesRead = $fileStream.Read($chunk,0,$bufsize) )
    {
        $retryCount = 0

        while ($retryCount -ne 30) {
            try {
                    $requestStream.write($chunk, 0, $bytesRead)
                    $requestStream.Flush()
                }
            catch { 
                    $retryCount += 0 
                }
        }
    }

    $FileStream.Close()
    $requestStream.Close()

现在,我不确定我该如何处理。我一直在考虑将我的块大小从 256mb 缩小到 TCP 数据包的大小,但据我所知,这些大小也会有所不同(最高 64Kb)。

所以,我正在寻找一种方法来以某种方式处理此连接断开,因为我目前不确定如何执行此操作。非常感谢任何帮助。

【问题讨论】:

    标签: powershell ftp ftpwebrequest


    【解决方案1】:

    在使用FtpWebRequest 中断连接后恢复传输的唯一方法是重新连接并开始写入文件末尾。

    为此使用FtpWebRequest.ContentOffset

    关于上传完整代码的相关问题(尽管针对 C#):
    How to download FTP files with automatic resume in case of disconnect


    或者使用可以自动恢复传输的 FTP 库。

    例如WinSCP .NET assembly 可以。有了它,可恢复的上传就变得如此简单:

    # Load WinSCP .NET assembly
    Add-Type -Path "WinSCPnet.dll"
    
    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions -Property @{
        Protocol = [WinSCP.Protocol]::Ftp
        HostName = "ftp.example.com"
        UserName = "user"
        Password = "mypassword"
    }
    
    $session = New-Object WinSCP.Session
    
    # Connect
    $session.Open($sessionOptions)
    
    # Resumable upload
    $session.PutFileToDirectory("C:\path\file.zip", "/home/user")
    

    (我是 WinSCP 的作者)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-08
      • 1970-01-01
      • 2017-06-06
      • 2014-04-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多