mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-09-10 01:05:42 +00:00
Added CreateDirectoryAsync to SftpClient (#1505)
* Added CreateDirectoryAsync to SftpClient * Use CreateDirectoryAsync for async test --------- Co-authored-by: Rob Hague <rob.hague00@gmail.com>
This commit is contained in:
@@ -429,6 +429,19 @@ namespace Renci.SshNet
|
||||
/// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
|
||||
void CreateDirectory(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously requests to create a remote directory specified by path.
|
||||
/// </summary>
|
||||
/// <param name="path">Directory path to create.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to observe.</param>
|
||||
/// <returns>A <see cref="Task"/> that represents the asynchronous create directory operation.</returns>
|
||||
/// <exception cref="ArgumentException"><paramref name="path"/> is <see langword="null"/> or contains only whitespace characters.</exception>
|
||||
/// <exception cref="SshConnectionException">Client is not connected.</exception>
|
||||
/// <exception cref="SftpPermissionDeniedException">Permission to create the directory was denied by the remote host. <para>-or-</para> A SSH command was denied by the server.</exception>
|
||||
/// <exception cref="SshException">A SSH error where <see cref="Exception.Message"/> is the message from the remote host.</exception>
|
||||
/// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
|
||||
Task CreateDirectoryAsync(string path, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Creates or opens a file for writing UTF-8 encoded text.
|
||||
/// </summary>
|
||||
|
||||
@@ -162,6 +162,14 @@ namespace Renci.SshNet.Sftp
|
||||
/// <param name="path">The path.</param>
|
||||
void RequestMkDir(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously performs SSH_FXP_MKDIR request.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to observe.</param>
|
||||
/// <returns>A <see cref="Task"/> that represents the asynchronous <c>SSH_FXP_MKDIR</c> operation.</returns>
|
||||
Task RequestMkDirAsync(string path, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Performs a <c>SSH_FXP_OPEN</c> request.
|
||||
/// </summary>
|
||||
|
||||
@@ -1544,6 +1544,44 @@ namespace Renci.SshNet.Sftp
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously performs SSH_FXP_MKDIR request.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to observe.</param>
|
||||
/// <returns>A <see cref="Task"/> that represents the asynchronous <c>SSH_FXP_MKDIR</c> operation.</returns>
|
||||
public async Task RequestMkDirAsync(string path, CancellationToken cancellationToken = default)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
#if NET || NETSTANDARD2_1_OR_GREATER
|
||||
await using (cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).TrySetCanceled(cancellationToken), tcs, useSynchronizationContext: false).ConfigureAwait(continueOnCapturedContext: false))
|
||||
#else
|
||||
using (cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).TrySetCanceled(cancellationToken), tcs, useSynchronizationContext: false))
|
||||
#endif // NET || NETSTANDARD2_1_OR_GREATER
|
||||
{
|
||||
SendRequest(new SftpMkDirRequest(ProtocolVersion,
|
||||
NextRequestId,
|
||||
path,
|
||||
_encoding,
|
||||
response =>
|
||||
{
|
||||
if (response.StatusCode == StatusCodes.Ok)
|
||||
{
|
||||
_ = tcs.TrySetResult(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
tcs.TrySetException(GetSftpException(response));
|
||||
}
|
||||
}));
|
||||
|
||||
_ = await tcs.Task.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs SSH_FXP_RMDIR request.
|
||||
/// </summary>
|
||||
|
||||
@@ -373,6 +373,32 @@ namespace Renci.SshNet
|
||||
_sftpSession.RequestMkDir(fullPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously requests to create a remote directory specified by path.
|
||||
/// </summary>
|
||||
/// <param name="path">Directory path to create.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to observe.</param>
|
||||
/// <returns>A <see cref="Task"/> that represents the asynchronous create directory operation.</returns>
|
||||
/// <exception cref="ArgumentException"><paramref name="path"/> is <see langword="null"/> or contains only whitespace characters.</exception>
|
||||
/// <exception cref="SshConnectionException">Client is not connected.</exception>
|
||||
/// <exception cref="SftpPermissionDeniedException">Permission to create the directory was denied by the remote host. <para>-or-</para> A SSH command was denied by the server.</exception>
|
||||
/// <exception cref="SshException">A SSH error where <see cref="Exception.Message"/> is the message from the remote host.</exception>
|
||||
/// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
|
||||
public async Task CreateDirectoryAsync(string path, CancellationToken cancellationToken = default)
|
||||
{
|
||||
CheckDisposed();
|
||||
ThrowHelper.ThrowIfNullOrWhiteSpace(path);
|
||||
|
||||
if (_sftpSession is null)
|
||||
{
|
||||
throw new SshConnectionException("Client not connected.");
|
||||
}
|
||||
|
||||
var fullPath = await _sftpSession.GetCanonicalPathAsync(path, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
await _sftpSession.RequestMkDirAsync(fullPath, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes remote directory specified by path.
|
||||
/// </summary>
|
||||
|
||||
+4
-4
@@ -239,15 +239,15 @@ namespace Renci.SshNet.IntegrationTests.OldIntegrationTests
|
||||
|
||||
Assert.AreEqual(sftp.WorkingDirectory, "/home/sshnet");
|
||||
|
||||
sftp.CreateDirectory("test1");
|
||||
await sftp.CreateDirectoryAsync("test1", CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
await sftp.ChangeDirectoryAsync("test1", CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
Assert.AreEqual(sftp.WorkingDirectory, "/home/sshnet/test1");
|
||||
|
||||
sftp.CreateDirectory("test1_1");
|
||||
sftp.CreateDirectory("test1_2");
|
||||
sftp.CreateDirectory("test1_3");
|
||||
await sftp.CreateDirectoryAsync("test1_1", CancellationToken.None).ConfigureAwait(false);
|
||||
await sftp.CreateDirectoryAsync("test1_2", CancellationToken.None).ConfigureAwait(false);
|
||||
await sftp.CreateDirectoryAsync("test1_3", CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
var files = sftp.ListDirectory(".");
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Renci.SshNet.IntegrationTests
|
||||
var testContent = "file content";
|
||||
|
||||
// Create new directory and check if it exists
|
||||
_sftpClient.CreateDirectory(testDirectory);
|
||||
await _sftpClient.CreateDirectoryAsync(testDirectory, CancellationToken.None).ConfigureAwait(false);
|
||||
Assert.IsTrue(await _sftpClient.ExistsAsync(testDirectory));
|
||||
|
||||
// Upload file and check if it exists
|
||||
|
||||
Reference in New Issue
Block a user