首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用winscpnet.dll并发上传文件

如何使用winscpnet.dll并发上传文件
EN

Stack Overflow用户
提问于 2017-10-19 12:21:01
回答 2查看 768关注 0票数 1

如何使用winscpnet.dll并发上传文件。我想使用脚本或c#将可以并发运行的winscp.exe实例设置为x个winscp.exe实例。

其他线程在下面的链接中提到了文档,但是这些代码将查看远程服务器,并使用session.GetFiles https://winscp.net/eng/docs/library_example_parallel_transfers#powershell同时下载x会话中的所有文件。

我正在寻找类似的做法,但想从一个使用session.PutFiles的目录上传文件。

winscpnet.dll代码中内置了一个函数,它将枚举远程目录,但没有做相反的事情。循环遍历本地目录并启动5个winscp.exe实例,当它们完成后,执行此操作,直到所有文件都完成session.Putfiles传输。

这一点很重要的原因是,将它们一次一个上传到远程sftp服务器所花费的时间比并发上传它们所需的时间要长得多。

EN

回答 2

Stack Overflow用户

发布于 2017-10-19 16:12:19

  • WinSCP .NET程序集中没有用于枚举本地文件的应用程序接口,因为这与远程连接无关。

实际上,在PowerShell中有一个这样的Get-ChildItem.

  • Other,代码将与下载代码几乎相同(除了使用Session.GetFiles).

而不是Session.PutFiles这样的明显区别

您引用的这篇文章现在包含了upload in parallel connections over SFTP protocol in C#的完整代码。

票数 1
EN

Stack Overflow用户

发布于 2017-10-19 22:46:39

如果你还需要它,那就来吧。

代码语言:javascript
复制
#Powershell script to upload files from a local dire 
param ( 
$sessionUrl = "sftp://tester:password;fingerprint=ssh-rsa 2048 ba:5d:a4:1b:0a:73:30:cf:90:dd:e3:ef:6c:9e:1d:94@localhost", 
$remotePath = "/", 
$localPath = "C:\Users\your\test\upload", 
$batches = 3 
) 

#Upload data to local Rebex Tiny SFTP 

try 
{ 
    # Load WinSCP .NET assembly 
    $dllPath = (Join-Path $PSScriptRoot "WinSCPnet.dll") 
    # Load WinSCP .NET assembly 
    Add-Type -Path $dllPath 

    $started = Get-Date 

    # Build list of local files and sort them from larges to smallest 
    $files = Get-ChildItem $localPath | Sort-Object Length -Descending 

    # Calculate total size of all files 
    $total = ($files | Measure-Object -Property Length -Sum).Sum 

    # And batch size 
    $batch = [int]($total / $batches) 

    Write-Host ("Will upload {0} files totaling {1} bytes in {2} parallel batches, {3} bytes on average in each" -f $files.Count, $total, $batches, $batch) 

    $start = 0 
    $sum = 0 
    $no = 0 

    for ($i = 0; $i -lt $files.Count; $i++) 
    { 
        $sum += $files[$i].Length 

        # Found enough files for the next batch 
        if (($sum -ge $batch) -or ($i -eq $files.Count - 1)) 
        { 
            Write-Host ("Starting batch {0} to upload {1} files totaling {2}" -f $no, ($i - $start + 1), $sum) 

            $fileList = $files[$start..$i] -join ";" 

            # Start the background job for the batch 
            Start-Job -Name "Batch $no" -ArgumentList $dllPath, $sessionUrl, $localPath, $remotePath, $no, $fileList { 
                param ( 
                    [Parameter(Position = 0)] 
                    $dllPath, 
                    [Parameter(Position = 1)] 
                    $sessionUrl, 
                    [Parameter(Position = 2)] 
                    $localPath, 
                    [Parameter(Position = 3)] 
                    $remotePath, 
                    [Parameter(Position = 4)] 
                    $no, 
                    [Parameter(Position = 5)] 
                    $fileList 
                ) 

                try 
                { 
                    Write-Host ("Starting batch {0}" -f $no) 

                    # Load WinSCP .NET assembly. 
                    # Need to use an absolute path as the Job is started from user's documents folder. 
                    Add-Type -Path $dllPath 

                    # Setup session options 
                    $sessionOptions = New-Object WinSCP.SessionOptions 
                    $sessionOptions.ParseUrl($sessionUrl) 

                    try 
                    { 
                        Write-Host ("Connecting batch {0}..." -f $no) 
                        $session = New-Object WinSCP.Session 

                        $session.Open($sessionOptions) 

                        $files = $fileList -split ";" 

                        # Upload the files selected for this batch 
                        foreach ($file in $files) 
                        { 
                            $localFilePath = "$localPath\$file" 
                            $remoteFilePath = "$remotePath/$file" 
                            Write-Host "Uploading $localFilePath to $remoteFilePath in $no" 

                            $session.PutFiles($session.EscapeFileMask($localFilePath), $remoteFilePath).Check() 
                        } 
                    } 
                    finally 
                    { 
                        # Disconnect, clean up 
                        $session.Dispose() 
                    } 

                    Write-Host ("Batch {0} done" -f $no) 
                } 
                catch [Exception] 
                { 
                    Write-Host $_.Exception.Message 
                    exit 1 
                } 
            } | Out-Null 

            # Reset for the next batch 
            $no++ 
            $sum = 0 
            $start = $i + 1 
        } 
    } 

    Write-Host "Waiting for batches to complete" 
    Get-Job | Receive-Job -Wait 

    Write-Host "Done" 

    $ended = Get-Date 
    Write-Host ("Took {0}" -f (New-TimeSpan -Start $started -End $ended)) 

    exit 0 
} 
catch [Exception] 
{ 
    Write-Host $_.Exception.Message 
    exit 1 
} 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46822798

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档