2017-06-27 28 views
1

私は米国からヨーロッパへの7.3キロバイトのファイルをチャンクにFTPするために使用しているPowerShellスクリプトを持っています。スクリプトは、接続が落ち、転送が停止するまでうまく動作します。PowerShellで接続が切断された後にFTPアップロードを再開するにはどうすればいいですか?

私は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)。

私は現時点でこれを行う方法がわからないので、何とかこの接続のドロップを処理する方法を探しています。どんな助けでも本当に感謝しています。

+1

あなたのコードでは、あまり意味がありません。接続が壊れている場合は、破損した接続に再度書き込みを試みることはできません。あなたは再接続する必要があります。 –

+0

このコードでどのように大きなファイルになるのか想像もできません。 –

+1

OK、接続**が**破損していない場合は、大きなファイルを取得します。 '$ retryCount -ne 30'条件は、$ retryCountをインクリメントしないので決して満たされないので、同じデータを無期限に書き続けます。 –

答えて

5

FtpWebRequestで接続を中断した後に転送を再開する唯一の方法は、再接続してファイルの最後に書き出しを開始することです。

FtpWebRequest.ContentOffsetです。

How to continue or resume FTP upload after interruption of internetを参照してください。


また、転送を自動的に再開できる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 
$transferResult = $session.PutFiles("C:\path\file.zip", "/home/user/file.zip").Check() 

(私はWinSCPのの著者です)

関連する問題