SSH.NETライブラリのSftpClient
クラスを使用してSFTPサーバーとの間でファイルをアップロードおよびダウンロードできることは知っていますが、このクラスを使用してSFTPサーバー上のリモートファイルをコピーまたは移動する方法がわかりません。 。また、インターネット上で関連資料が見つかりませんでした。 SSH.NETライブラリとC#を使用して、リモートファイルをディレクトリAからディレクトリBにコピーまたは移動するにはどうすればよいですか。
pdate:以下のコードを使用してSshClient
クラスを試してみましたが、エラーも例外も発生しません。
ConnectionInfo ConnNfo = new ConnectionInfo("FTPHost", 22, "FTPUser",
new AuthenticationMethod[]{
// Pasword based Authentication
new PasswordAuthenticationMethod("FTPUser","FTPPass")
}
);
using (var ssh = new SshClient(ConnNfo))
{
ssh.Connect();
if (ssh.IsConnected)
{
string comm = "pwd";
using (var cmd = ssh.CreateCommand(comm))
{
var returned = cmd.Execute();
var output = cmd.Result;
var err = cmd.Error;
var stat = cmd.ExitStatus;
}
}
ssh.Disconnect();
}
Visual Studioコンソールで、以下の出力が得られます。
* SshNet.Logging Verbose:1:サーバーへのSendMessage'ChannelRequestMessage ':' SSH_MSG_CHANNEL_REQUEST:#152199 '。
SshNet.Logging詳細:1:サーバーからのReceiveMessage: 'ChannelFailureMessage': 'SSH_MSG_CHANNEL_FAILURE:#0'。*
リモートファイルの移動は、SSH.NETライブラリを使用して実行できます。ここで入手可能: https://github.com/sshnet/SSH.NET
これは、最初のファイルをあるソースフォルダーから別のソースフォルダーに移動するためのサンプルコードです。 FTPの設定に従って、クラスにプライベート変数を設定します。
using System;
using System.Linq;
using System.Collections.Generic;
using Renci.SshNet;
using Renci.SshNet.Sftp;
using System.IO;
using System.Configuration;
using System.IO.Compression;
public class RemoteFileOperations
{
private string ftpPathSrcFolder = "/Path/Source/";//path should end with /
private string ftpPathDestFolder = "/Path/Archive/";//path should end with /
private string ftpServerIP = "Target IP";
private int ftpPortNumber = 80;//change to appropriate port number
private string ftpUserID = "FTP USer Name";//
private string ftpPassword = "FTP Password";
/// <summary>
/// Move first file from one source folder to another.
/// Note: Modify code and add a for loop to move all files of the folder
/// </summary>
public void MoveFolderToArchive()
{
using (SftpClient sftp = new SftpClient(ftpServerIP, ftpPortNumber, ftpUserID, ftpPassword))
{
SftpFile eachRemoteFile = sftp.ListDirectory(ftpPathSrcFolder).First();//Get first file in the Directory
if(eachRemoteFile.IsRegularFile)//Move only file
{
bool eachFileExistsInArchive = CheckIfRemoteFileExists(sftp, ftpPathDestFolder, eachRemoteFile.Name);
//MoveTo will result in error if filename alredy exists in the target folder. Prevent that error by cheking if File name exists
string eachFileNameInArchive = eachRemoteFile.Name;
if (eachFileExistsInArchive)
{
eachFileNameInArchive = eachFileNameInArchive + "_" + DateTime.Now.ToString("MMddyyyy_HHmmss");//Change file name if the file already exists
}
eachRemoteFile.MoveTo(ftpPathDestFolder + eachFileNameInArchive);
}
}
}
/// <summary>
/// Checks if Remote folder contains the given file name
/// </summary>
public bool CheckIfRemoteFileExists(SftpClient sftpClient, string remoteFolderName, string remotefileName)
{
bool isFileExists = sftpClient
.ListDirectory(remoteFolderName)
.Any(
f => f.IsRegularFile &&
f.Name.ToLower() == remotefileName.ToLower()
);
return isFileExists;
}
}
SSH.NETのSftpClient
に加えて、ScpClient
の問題が発生したときに機能したより単純なSftpClient
もあります。 ScpClient
にはアップロード/ダウンロード機能しかありませんが、それで私のユースケースは満足しました。
アップロード:
using (ScpClient client = new ScpClient(Host, username, password))
{
client.Connect();
using (Stream localFile = File.OpenRead(localFilePath))
{
client.Upload(localFile, remoteFilePath);
}
}
ダウンロード:
using (ScpClient client = new ScpClient(Host, username, password))
{
client.Connect();
using (Stream localFile = File.Create(localFilePath))
{
client.Download(remoteFilePath, localFile);
}
}
RenciのNuGetパッケージSSH.NETでは、次のものを使用します。
using Renci.SshNet;
using Renci.SshNet.SftpClient;
...
SftpClient _sftp = new SftpClient(_Host, _username, _password);
ファイルを移動するには:
var inFile = _sftp.Get(inPath);
inFile.MoveTo(outPath);
ファイルをコピーするには:
var fsIn = _sftp.OpenRead(inPath);
var fsOut = _sftp.OpenWrite(outPath);
int data;
while ((data = fsIn.ReadByte()) != -1)
fsOut.WriteByte((byte)data);
fsOut.Flush();
fsIn.Close();
fsOut.Close();