/*******************************************************************************
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use
* this file except in compliance with the License. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file.
* This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
* *****************************************************************************
* __ _ _ ___
* ( )( \/\/ )/ __)
* /__\ \ / \__ \
* (_)(_) \/\/ (___/
*
* AWS SDK for .NET
* API Version: 2006-03-01
*
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using Amazon.Runtime.Internal.Util;
using Amazon.S3.Model;
using Amazon.S3.Transfer.Internal;
using Amazon.Util;
using System.Globalization;
namespace Amazon.S3.Transfer
{
///
///
/// Provides a high level utility for managing transfers to and from Amazon S3.
///
///
/// TransferUtility provides a simple API for
/// uploading content to and downloading content
/// from Amazon S3. It makes extensive use of Amazon S3 multipart uploads to
/// achieve enhanced throughput, performance, and reliability.
///
///
/// When uploading large files by specifying file paths instead of a stream,
/// TransferUtility uses multiple threads to upload
/// multiple parts of a single upload at once. When dealing with large content
/// sizes and high bandwidth, this can increase throughput significantly.
///
///
///
///
/// Transfers are stored in memory. If the application is restarted,
/// previous transfers are no longer accessible. In this situation, if necessary,
/// you should clean up any multipart uploads that are incomplete.
///
///
public partial class TransferUtility : ITransferUtility
{
#region UploadDirectory
///
/// Uploads files from a specified directory.
/// The object key is derived from the file names
/// inside the directory.
/// For large uploads, the file will be divided and uploaded in parts using
/// Amazon S3's multipart API. The parts will be reassembled as one object in
/// Amazon S3.
///
///
///
/// If you are uploading large files, TransferUtility will use multipart upload to fulfill the request.
/// If a multipart upload is interrupted, TransferUtility will attempt to abort the multipart upload.
/// Under certain circumstances (network outage, power failure, etc.), TransferUtility will not be able
/// to abort the multipart upload. In this case, in order to stop getting charged for the storage of uploaded parts,
/// you should manually invoke TransferUtility.AbortMultipartUploads() to abort the incomplete multipart uploads.
///
///
///
/// The source directory, that is, the directory containing the files to upload.
///
///
/// The target Amazon S3 bucket, that is, the name of the bucket to upload the files to.
///
public void UploadDirectory(string directory, string bucketName)
{
UploadDirectoryHelper(directory, bucketName);
}
///
/// Uploads files from a specified directory.
/// The object key is derived from the file names
/// inside the directory.
/// For large uploads, the file will be divided and uploaded in parts using
/// Amazon S3's multipart API. The parts will be reassembled as one object in
/// Amazon S3.
///
///
///
/// If you are uploading large files, TransferUtility will use multipart upload to fulfill the request.
/// If a multipart upload is interrupted, TransferUtility will attempt to abort the multipart upload.
/// Under certain circumstances (network outage, power failure, etc.), TransferUtility will not be able
/// to abort the multipart upload. In this case, in order to stop getting charged for the storage of uploaded parts,
/// you should manually invoke TransferUtility.AbortMultipartUploads() to abort the incomplete multipart uploads.
///
///
///
/// The source directory, that is, the directory containing the files to upload.
///
///
/// The target Amazon S3 bucket, that is, the name of the bucket to upload the files to.
///
///
/// A pattern used to identify the files from the source directory to upload.
///
///
/// A search option that specifies whether to recursively search for files to upload
/// in subdirectories.
///
public void UploadDirectory(string directory, string bucketName, string searchPattern, SearchOption searchOption)
{
UploadDirectoryHelper(directory, bucketName, searchPattern, searchOption);
}
///
/// Uploads files from a specified directory.
/// The object key is derived from the file names
/// inside the directory.
/// For large uploads, the file will be divided and uploaded in parts using
/// Amazon S3's multipart API. The parts will be reassembled as one object in
/// Amazon S3.
///
///
///
/// If you are uploading large files, TransferUtility will use multipart upload to fulfill the request.
/// If a multipart upload is interrupted, TransferUtility will attempt to abort the multipart upload.
/// Under certain circumstances (network outage, power failure, etc.), TransferUtility will not be able
/// to abort the multipart upload. In this case, in order to stop getting charged for the storage of uploaded parts,
/// you should manually invoke TransferUtility.AbortMultipartUploads() to abort the incomplete multipart uploads.
///
///
///
/// The request that contains all the parameters required to upload a directory.
///
public void UploadDirectory(TransferUtilityUploadDirectoryRequest request)
{
UploadDirectoryHelper(request);
}
///
/// Initiates the asynchronous execution of the UploadDirectory operation.
///
///
///
///
/// If you are uploading large files, TransferUtility will use multipart upload to fulfill the request.
/// If a multipart upload is interrupted, TransferUtility will attempt to abort the multipart upload.
/// Under certain circumstances (network outage, power failure, etc.), TransferUtility will not be able
/// to abort the multipart upload. In this case, in order to stop getting charged for the storage of uploaded parts,
/// you should manually invoke TransferUtility.AbortMultipartUploads() to abort the incomplete multipart uploads.
///
///
///
/// The source directory, that is, the directory containing the files to upload.
///
///
/// The target Amazon S3 bucket, that is, the name of the bucket to upload the files to.
///
/// An AsyncCallback delegate that is invoked when the operation completes.
/// A user-defined state object that is passed to the callback procedure.
/// Retrieve this object from within the callback procedure using the AsyncState property.
///
///
///
///
/// An IAsyncResult that can be used to poll, or wait for results, or both.
/// This value is also needed when invoking EndUploadDirectory.
public IAsyncResult BeginUploadDirectory(string directory, string bucketName, AsyncCallback callback, object state)
{
TransferUtilityUploadDirectoryRequest request = new TransferUtilityUploadDirectoryRequest()
{
BucketName = bucketName,
Directory = directory
};
return BeginUploadDirectory(request, callback, state);
}
///
/// Initiates the asynchronous execution of the UploadDirectory operation.
///
///
///
///
/// If you are uploading large files, TransferUtility will use multipart upload to fulfill the request.
/// If a multipart upload is interrupted, TransferUtility will attempt to abort the multipart upload.
/// Under certain circumstances (network outage, power failure, etc.), TransferUtility will not be able
/// to abort the multipart upload. In this case, in order to stop getting charged for the storage of uploaded parts,
/// you should manually invoke TransferUtility.AbortMultipartUploads() to abort the incomplete multipart uploads.
///
///
///
/// The source directory, that is, the directory containing the files to upload.
///
///
/// The target Amazon S3 bucket, that is, the name of the bucket to upload the files to.
///
///
/// A pattern used to identify the files from the source directory to upload.
///
///
/// A search option that specifies whether to recursively search for files to upload
/// in subdirectories.
///
/// An AsyncCallback delegate that is invoked when the operation completes.
/// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback procedure using the AsyncState property.
///
///
///
/// An IAsyncResult that can be used to poll, or wait for results, or both.
/// This value is also needed when invoking EndUploadDirectory.
public IAsyncResult BeginUploadDirectory(string directory, string bucketName, string searchPattern, SearchOption searchOption, AsyncCallback callback, object state)
{
TransferUtilityUploadDirectoryRequest request = new TransferUtilityUploadDirectoryRequest()
{
BucketName = bucketName,
Directory = directory,
SearchPattern = searchPattern,
SearchOption = searchOption
};
return BeginUploadDirectory(request, callback, state);
}
///
/// Initiates the asynchronous execution of the UploadDirectory operation.
///
///
///
///
/// If you are uploading large files, TransferUtility will use multipart upload to fulfill the request.
/// If a multipart upload is interrupted, TransferUtility will attempt to abort the multipart upload.
/// Under certain circumstances (network outage, power failure, etc.), TransferUtility will not be able
/// to abort the multipart upload. In this case, in order to stop getting charged for the storage of uploaded parts,
/// you should manually invoke TransferUtility.AbortMultipartUploads() to abort the incomplete multipart uploads.
///
///
///
/// The request that contains all the parameters required to upload a directory.
///
/// An AsyncCallback delegate that is invoked when the operation completes.
/// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback procedure using the AsyncState property.
///
///
///
/// An IAsyncResult that can be used to poll, or wait for results, or both.
/// This value is also needed when invoking EndUploadDirectory.
public IAsyncResult BeginUploadDirectory(TransferUtilityUploadDirectoryRequest request, AsyncCallback callback, object state)
{
validate(request);
UploadDirectoryCommand command = new UploadDirectoryCommand(this, this._config, request);
return beginOperation(command, callback, state);
}
///
/// Finishes the asynchronous execution of the UploadDirectory operation.
///
///
/// The IAsyncResult returned by the call to BeginUploadDirectory.
///
///
///
public void EndUploadDirectory(IAsyncResult asyncResult)
{
endOperation(asyncResult);
}
#endregion
#region Upload
///
/// Uploads the specified file.
/// The object key is derived from the file's name.
/// Multiple threads are used to read the file and perform multiple uploads in parallel.
/// For large uploads, the file will be divided and uploaded in parts using
/// Amazon S3's multipart API. The parts will be reassembled as one object in
/// Amazon S3.
///
///
///
/// If you are uploading large files, TransferUtility will use multipart upload to fulfill the request.
/// If a multipart upload is interrupted, TransferUtility will attempt to abort the multipart upload.
/// Under certain circumstances (network outage, power failure, etc.), TransferUtility will not be able
/// to abort the multipart upload. In this case, in order to stop getting charged for the storage of uploaded parts,
/// you should manually invoke TransferUtility.AbortMultipartUploads() to abort the incomplete multipart uploads.
///
///
///
/// The file path of the file to upload.
///
///
/// The target Amazon S3 bucket, that is, the name of the bucket to upload the file to.
///
public void Upload(string filePath, string bucketName)
{
UploadHelper(filePath, bucketName);
}
///
/// Uploads the specified file.
/// Multiple threads are used to read the file and perform multiple uploads in parallel.
/// For large uploads, the file will be divided and uploaded in parts using
/// Amazon S3's multipart API. The parts will be reassembled as one object in
/// Amazon S3.
///
///
///
/// If you are uploading large files, TransferUtility will use multipart upload to fulfill the request.
/// If a multipart upload is interrupted, TransferUtility will attempt to abort the multipart upload.
/// Under certain circumstances (network outage, power failure, etc.), TransferUtility will not be able
/// to abort the multipart upload. In this case, in order to stop getting charged for the storage of uploaded parts,
/// you should manually invoke TransferUtility.AbortMultipartUploads() to abort the incomplete multipart uploads.
///
///
///
/// The file path of the file to upload.
///
///
/// The target Amazon S3 bucket, that is, the name of the bucket to upload the file to.
///
///
/// The key under which the Amazon S3 object is stored.
///
public void Upload(string filePath, string bucketName, string key)
{
UploadHelper(filePath, bucketName, key);
}
///
/// Uploads the contents of the specified stream.
/// For large uploads, the file will be divided and uploaded in parts using
/// Amazon S3's multipart API. The parts will be reassembled as one object in
/// Amazon S3.
///
///
///
/// If you are uploading large files, TransferUtility will use multipart upload to fulfill the request.
/// If a multipart upload is interrupted, TransferUtility will attempt to abort the multipart upload.
/// Under certain circumstances (network outage, power failure, etc.), TransferUtility will not be able
/// to abort the multipart upload. In this case, in order to stop getting charged for the storage of uploaded parts,
/// you should manually invoke TransferUtility.AbortMultipartUploads() to abort the incomplete multipart uploads.
///
///
///
/// The stream to read to obtain the content to upload.
///
///
/// The target Amazon S3 bucket, that is, the name of the bucket to upload the stream to.
///
///
/// The key under which the Amazon S3 object is stored.
///
public void Upload(Stream stream, string bucketName, string key)
{
UploadHelper(stream, bucketName, key);
}
///
/// Uploads the file or stream specified by the request.
/// To track the progress of the upload,
/// add an event listener to the request's UploadProgressEvent.
/// For large uploads, the file will be divided and uploaded in parts using
/// Amazon S3's multipart API. The parts will be reassembled as one object in
/// Amazon S3.
///
///
///
/// If you are uploading large files, TransferUtility will use multipart upload to fulfill the request.
/// If a multipart upload is interrupted, TransferUtility will attempt to abort the multipart upload.
/// Under certain circumstances (network outage, power failure, etc.), TransferUtility will not be able
/// to abort the multipart upload. In this case, in order to stop getting charged for the storage of uploaded parts,
/// you should manually invoke TransferUtility.AbortMultipartUploads() to abort the incomplete multipart uploads.
///
///
///
/// Contains all the parameters required to upload to Amazon S3.
///
public void Upload(TransferUtilityUploadRequest request)
{
this.UploadHelper(request);
}
///
/// Initiates the asynchronous execution of the Upload operation.
///
///
///
///
/// If you are uploading large files, TransferUtility will use multipart upload to fulfill the request.
/// If a multipart upload is interrupted, TransferUtility will attempt to abort the multipart upload.
/// Under certain circumstances (network outage, power failure, etc.), TransferUtility will not be able
/// to abort the multipart upload. In this case, in order to stop getting charged for the storage of uploaded parts,
/// you should manually invoke TransferUtility.AbortMultipartUploads() to abort the incomplete multipart uploads.
///
///
///
/// The file path of the file to upload.
///
///
/// The target Amazon S3 bucket, that is, the name of the bucket to upload the file to.
///
/// An AsyncCallback delegate that is invoked when the operation completes.
/// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback procedure using the AsyncState property.
///
///
///
/// An IAsyncResult that can be used to poll, or wait for results, or both.
/// This values is also needed when invoking EndUpload.
public IAsyncResult BeginUpload(string filePath, string bucketName, AsyncCallback callback, object state)
{
if (string.IsNullOrEmpty(filePath))
{
throw new ArgumentNullException("filePath");
}
if (!File.Exists(filePath))
{
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The file {0} does not exists!", filePath));
}
TransferUtilityUploadRequest request = new TransferUtilityUploadRequest()
{
BucketName = bucketName,
FilePath = filePath
};
return BeginUpload(request, callback, state);
}
///
/// Initiates the asynchronous execution of the Upload operation.
///
///
///
///
/// If you are uploading large files, TransferUtility will use multipart upload to fulfill the request.
/// If a multipart upload is interrupted, TransferUtility will attempt to abort the multipart upload.
/// Under certain circumstances (network outage, power failure, etc.), TransferUtility will not be able
/// to abort the multipart upload. In this case, in order to stop getting charged for the storage of uploaded parts,
/// you should manually invoke TransferUtility.AbortMultipartUploads() to abort the incomplete multipart uploads.
///
///
///
/// The file path of the file to upload.
///
///
/// The target Amazon S3 bucket, that is, the name of the bucket to upload the file to.
///
///
/// The key under which the Amazon S3 object is stored.
///
/// An AsyncCallback delegate that is invoked when the operation completes.
/// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback procedure using the AsyncState property.
///
///
///
/// An IAsyncResult that can be used to poll, or wait for results, or both.
/// This values is also needed when invoking EndUpload.
public IAsyncResult BeginUpload(string filePath, string bucketName, string key, AsyncCallback callback, object state)
{
if (string.IsNullOrEmpty(filePath))
{
throw new ArgumentNullException("filePath");
}
if (!File.Exists(filePath))
{
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The file {0} does not exists!", filePath));
}
TransferUtilityUploadRequest request = new TransferUtilityUploadRequest()
{
BucketName = bucketName,
Key = key,
FilePath = filePath
};
return BeginUpload(request, callback, state);
}
///
/// Initiates the asynchronous execution of the Upload operation.
///
///
///
///
/// If you are uploading large files, TransferUtility will use multipart upload to fulfill the request.
/// If a multipart upload is interrupted, TransferUtility will attempt to abort the multipart upload.
/// Under certain circumstances (network outage, power failure, etc.), TransferUtility will not be able
/// to abort the multipart upload. In this case, in order to stop getting charged for the storage of uploaded parts,
/// you should manually invoke TransferUtility.AbortMultipartUploads() to abort the incomplete multipart uploads.
///
///
///
/// The stream to read to obtain the content to upload.
///
///
/// The target Amazon S3 bucket, that is, the name of the bucket to upload the stream to.
///
///
/// The key under which the Amazon S3 object is stored.
///
/// An AsyncCallback delegate that is invoked when the operation completes.
/// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback procedure using the AsyncState property.
///
///
///
/// An IAsyncResult that can be used to poll, or wait for results, or both.
/// This values is also needed when invoking EndUpload.
public IAsyncResult BeginUpload(Stream stream, string bucketName, string key, AsyncCallback callback, object state)
{
if (stream == null)
{
throw new ArgumentNullException("stream");
}
if (string.IsNullOrEmpty(key))
{
throw new ArgumentNullException("key");
}
TransferUtilityUploadRequest request = new TransferUtilityUploadRequest()
{
BucketName = bucketName,
Key = key,
InputStream = stream
};
return BeginUpload(request, callback, state);
}
///
/// Initiates the asynchronous execution of the Upload operation.
///
///
///
///
/// If you are uploading large files, TransferUtility will use multipart upload to fulfill the request.
/// If a multipart upload is interrupted, TransferUtility will attempt to abort the multipart upload.
/// Under certain circumstances (network outage, power failure, etc.), TransferUtility will not be able
/// to abort the multipart upload. In this case, in order to stop getting charged for the storage of uploaded parts,
/// you should manually invoke TransferUtility.AbortMultipartUploads() to abort the incomplete multipart uploads.
///
///
///
/// Contains all the parameters required to upload to Amazon S3.
///
/// An AsyncCallback delegate that is invoked when the operation completes.
/// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback procedure using the AsyncState property.
///
///
///
/// An IAsyncResult that can be used to poll, or wait for results, or both.
/// This values is also needed when invoking EndUpload.
public IAsyncResult BeginUpload(TransferUtilityUploadRequest request, AsyncCallback callback, object state)
{
validate(request);
BaseCommand command;
if (request.ContentLength < this._config.MinSizeBeforePartUpload)
{
command = new SimpleUploadCommand(this._s3Client, this._config, request);
}
else
{
command = new MultipartUploadCommand(this._s3Client, this._config, request);
}
return beginOperation(command, callback, state);
}
///
/// Finishes the asynchronous execution of the Upload operation.
///
///
/// The IAsyncResult returned by the call to BeginUpload.
///
///
///
public void EndUpload(IAsyncResult asyncResult)
{
endOperation(asyncResult);
}
#endregion
#region OpenStream
///
/// Returns a stream from which the caller can read the content from the specified
/// Amazon S3 bucket and key.
/// The caller of this method is responsible for closing the stream.
///
///
/// The name of the bucket.
///
///
/// The object key.
///
///
/// A stream of the contents from the specified Amazon S3 and key.
///
public Stream OpenStream(string bucketName, string key)
{
return OpenStreamHelper(bucketName, key);
}
///
/// Returns a stream to read the contents from Amazon S3 as
/// specified by the TransferUtilityOpenStreamRequest.
/// The caller of this method is responsible for closing the stream.
///
///
/// Contains all the parameters required to open a stream to an S3 object.
///
///
/// A stream of the contents from Amazon S3.
///
public Stream OpenStream(TransferUtilityOpenStreamRequest request)
{
return OpenStreamHelper(request);
}
///
/// Initiates the asynchronous execution of the OpenStream operation.
///
///
///
/// The name of the bucket.
///
///
/// The object key.
///
/// An AsyncCallback delegate that is invoked when the operation completes.
/// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback procedure using the AsyncState property.
///
///
///
/// An IAsyncResult that can be used to poll, or wait for results, or both.
/// This values is also needed when invoking EndOpenStream.
public IAsyncResult BeginOpenStream(string bucketName, string key, AsyncCallback callback, object state)
{
TransferUtilityOpenStreamRequest request = new TransferUtilityOpenStreamRequest()
{
BucketName = bucketName,
Key = key
};
return BeginOpenStream(request, callback, state);
}
///
/// Initiates the asynchronous execution of the OpenStream operation.
///
///
///
/// Contains all the parameters required to open a stream to an Amazon S3 object.
///
/// An AsyncCallback delegate that is invoked when the operation completes.
/// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback procedure using the AsyncState property.
///
///
///
/// An IAsyncResult that can be used to poll, or wait for results, or both.
/// This values is also needed when invoking EndOpenStream.
public IAsyncResult BeginOpenStream(TransferUtilityOpenStreamRequest request, AsyncCallback callback, object state)
{
OpenStreamCommand command = new OpenStreamCommand(this._s3Client, request);
return beginOperation(command, callback, state);
}
///
/// Finishes the asynchronous execution of the OpenStream operation.
///
///
/// The IAsyncResult returned by the call to BeginOpenStream.
///
///
///
public Stream EndOpenStream(IAsyncResult asyncResult)
{
return endOperation(asyncResult) as Stream;
}
#endregion
#region Download
///
/// Downloads the content from Amazon S3 and writes it to the specified file.
///
///
/// The file path where the content from Amazon S3 will be written to.
///
///
/// The name of the bucket containing the Amazon S3 object to download.
///
///
/// The key under which the Amazon S3 object is stored.
///
public void Download(string filePath, string bucketName, string key)
{
DownloadHelper(filePath, bucketName, key);
}
///
/// Downloads the content from Amazon S3 and writes it to the specified file.
/// If the key is not specified in the request parameter,
/// the file name will used as the key name.
///
///
/// Contains all the parameters required to download an Amazon S3 object.
///
public void Download(TransferUtilityDownloadRequest request)
{
DownloadHelper(request);
}
///
/// Initiates the asynchronous execution of the Download operation.
///
///
///
/// The file path where the content from Amazon S3 will be written to.
///
///
/// The name of the bucket containing the Amazon S3 object to download.
///
///
/// The key under which the Amazon S3 object is stored.
///
/// An AsyncCallback delegate that is invoked when the operation completes.
/// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback procedure using the AsyncState property.
///
///
///
/// An IAsyncResult that can be used to poll, or wait for results, or both.
/// This values is also needed when invoking EndDownload.
public IAsyncResult BeginDownload(string filePath, string bucketName, string key, AsyncCallback callback, object state)
{
TransferUtilityDownloadRequest request = new TransferUtilityDownloadRequest()
{
BucketName = bucketName,
Key = key,
FilePath = filePath
};
return BeginDownload(request, callback, state);
}
///
/// Initiates the asynchronous execution of the Download operation.
///
///
///
/// Contains all the parameters required to download an Amazon S3 object.
///
/// An AsyncCallback delegate that is invoked when the operation completes.
/// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback procedure using the AsyncState property.
///
///
///
/// An IAsyncResult that can be used to poll, or wait for results, or both.
/// This values is also needed when invoking EndDownload.
public IAsyncResult BeginDownload(TransferUtilityDownloadRequest request, AsyncCallback callback, object state)
{
BaseCommand command = new DownloadCommand(this._s3Client, request);
return beginOperation(command, callback, state);
}
///
/// Finishes the asynchronous execution of the Download operation.
///
///
/// The IAsyncResult returned by the call to BeginDownload.
///
///
///
public void EndDownload(IAsyncResult asyncResult)
{
endOperation(asyncResult);
}
#endregion
#region DownloadDirectory
///
/// Downloads the objects in Amazon S3 that have a key that starts with the value
/// specified by s3Directory.
///
///
/// The name of the bucket containing the Amazon S3 objects to download.
///
///
/// The directory in Amazon S3 to download.
///
///
/// The local directory to download the objects to.
///
public void DownloadDirectory(string bucketName, string s3Directory, string localDirectory)
{
DownloadDirectoryHelper(bucketName, s3Directory, localDirectory);
}
///
/// Downloads the objects in Amazon S3 that have a key that starts with the value
/// specified by the S3Directory
/// property of the passed in TransferUtilityDownloadDirectoryRequest object.
///
///
/// Contains all the parameters required to download objects from Amazon S3
/// into a local directory.
///
public void DownloadDirectory(TransferUtilityDownloadDirectoryRequest request)
{
DownloadDirectoryHelper(request);
}
///
/// Initiates the asynchronous execution of the DownloadDirectory operation.
///
///
///
/// The name of the bucket containing the Amazon S3 objects to download.
///
///
/// The directory in Amazon S3 to download.
///
///
/// The local directory to download the objects to.
///
/// An AsyncCallback delegate that is invoked when the operation completes.
/// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback procedure using the AsyncState property.
///
///
///
/// An IAsyncResult that can be used to poll, or wait for results, or both.
/// This values is also needed when invoking EndDownloadDirectory.
public IAsyncResult BeginDownloadDirectory(string bucketName, string s3Directory, string localDirectory, AsyncCallback callback, object state)
{
TransferUtilityDownloadDirectoryRequest request = new TransferUtilityDownloadDirectoryRequest()
{
BucketName = bucketName,
S3Directory = s3Directory,
LocalDirectory = localDirectory
};
return BeginDownloadDirectory(request, callback, state);
}
///
/// Initiates the asynchronous execution of the DownloadDirectory operation.
///
///
///
/// Contains all the parameters required to download objects from a directory in Amazon S3
/// to a local directory.
///
/// An AsyncCallback delegate that is invoked when the operation completes.
/// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback procedure using the AsyncState property.
///
///
///
/// An IAsyncResult that can be used to poll, or wait for results, or both.
/// This values is also needed when invoking EndDownload.
public IAsyncResult BeginDownloadDirectory(TransferUtilityDownloadDirectoryRequest request, AsyncCallback callback, object state)
{
BaseCommand command = new DownloadDirectoryCommand(this._s3Client, request);
return beginOperation(command, callback, state);
}
///
/// Finishes the asynchronous execution of the DownloadDirectory operation.
///
///
/// The IAsyncResult returned by the call to BeginDownloadDirectory.
///
///
///
public void EndDownloadDirectory(IAsyncResult asyncResult)
{
endOperation(asyncResult);
}
#endregion
#region AbortMultipartUploads
///
/// Aborts the multipart uploads that were initiated before the specified date.
///
///
/// The name of the bucket containing multipart uploads.
///
///
/// The date before which the multipart uploads were initiated.
///
public void AbortMultipartUploads(string bucketName, DateTime initiatedDate)
{
AbortMultipartUploadsHelper(bucketName, initiatedDate);
}
///
/// Initiates the asynchronous execution of the AbortMultipartUploads operation.
///
///
///
/// The name of the bucket containing multipart uploads.
///
///
/// The date before which the multipart uploads were initiated.
///
/// An AsyncCallback delegate that is invoked when the operation completes.
/// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback procedure using the AsyncState property.
///
///
///
/// An IAsyncResult that can be used to poll, or wait for results, or both.
/// This values is also needed when invoking EndAbortMultipartUploads.
public IAsyncResult BeginAbortMultipartUploads(string bucketName, DateTime initiatedDate, AsyncCallback callback, object state)
{
BaseCommand command = new AbortMultipartUploadsCommand(this._s3Client, bucketName, initiatedDate);
return beginOperation(command, callback, state);
}
///
/// Finishes the asynchronous execution of the AbortMultipartUploads operation.
///
///
/// The IAsyncResult returned by the call to BeginAbortMultipartUploads.
///
///
///
public void EndAbortMultipartUploads(IAsyncResult asyncResult)
{
endOperation(asyncResult);
}
#endregion
#region UploadDirectory helper methods
private void UploadDirectoryHelper(string directory, string bucketName)
{
var request = ConstructUploadDirectoryRequest(directory, bucketName);
UploadDirectoryHelper(request);
}
private void UploadDirectoryHelper(string directory, string bucketName, string searchPattern, SearchOption searchOption)
{
var request = ConstructUploadDirectoryRequest(directory, bucketName, searchPattern, searchOption);
UploadDirectoryHelper(request);
}
private void UploadDirectoryHelper(TransferUtilityUploadDirectoryRequest request)
{
CheckForBlockedArn(request.BucketName, "UploadDirectory");
validate(request);
UploadDirectoryCommand command = new UploadDirectoryCommand(this, this._config, request);
command.Execute();
}
#endregion
#region Upload helper methods
private void UploadHelper(string filePath, string bucketName)
{
var request = ConstructUploadRequest(filePath, bucketName);
UploadHelper(request);
}
///
/// Uploads the specified file.
/// Multiple threads are used to read the file and perform multiple uploads in parallel.
/// For large uploads, the file will be divided and uploaded in parts using
/// Amazon S3's multipart API. The parts will be reassembled as one object in
/// Amazon S3.
///
///
/// The file path of the file to upload.
///
///
/// The target Amazon S3 bucket, that is, the name of the bucket to upload the file to.
///
///
/// The key under which the Amazon S3 object is stored.
///
private void UploadHelper(string filePath, string bucketName, string key)
{
var request = ConstructUploadRequest(filePath, bucketName, key);
UploadHelper(request);
}
///
/// Uploads the contents of the specified stream.
/// For large uploads, the file will be divided and uploaded in parts using
/// Amazon S3's multipart API. The parts will be reassembled as one object in
/// Amazon S3.
///
///
/// The stream to read to obtain the content to upload.
///
///
/// The target Amazon S3 bucket, that is, the name of the bucket to upload the stream to.
///
///
/// The key under which the Amazon S3 object is stored.
///
private void UploadHelper(Stream stream, string bucketName, string key)
{
var request = ConstructUploadRequest(stream, bucketName, key);
UploadHelper(request);
}
///
/// Uploads the file or stream specified by the request.
/// To track the progress of the upload,
/// add an event listener to the request's UploadProgressEvent.
/// For large uploads, the file will be divided and uploaded in parts using
/// Amazon S3's multipart API. The parts will be reassembled as one object in
/// Amazon S3.
///
///
/// Contains all the parameters required to upload to Amazon S3.
///
private void UploadHelper(TransferUtilityUploadRequest request)
{
CheckForBlockedArn(request.BucketName, "Upload");
var command = GetUploadCommand(request);
command.Execute();
}
#endregion
#region OpenStream helper methods
private Stream OpenStreamHelper(string bucketName, string key)
{
TransferUtilityOpenStreamRequest request = new TransferUtilityOpenStreamRequest()
{
BucketName = bucketName,
Key = key
};
return OpenStreamHelper(request);
}
private Stream OpenStreamHelper(TransferUtilityOpenStreamRequest request)
{
CheckForBlockedArn(request.BucketName, "OpenStream");
OpenStreamCommand command = new OpenStreamCommand(this._s3Client, request);
command.Execute();
return command.ResponseStream;
}
#endregion
#region Download helper methods
private void DownloadHelper(string filePath, string bucketName, string key)
{
TransferUtilityDownloadRequest request = ConstructDownloadRequest(filePath, bucketName, key);
DownloadHelper(request);
}
private void DownloadHelper(TransferUtilityDownloadRequest request)
{
CheckForBlockedArn(request.BucketName, "Download");
BaseCommand command = new DownloadCommand(this._s3Client, request);
command.Execute();
}
#endregion
#region DownloadDirectory helper methods
private void DownloadDirectoryHelper(string bucketName, string s3Directory, string localDirectory)
{
var request = ConstructDownloadDirectoryRequest(bucketName, s3Directory, localDirectory);
DownloadDirectoryHelper(request);
}
private void DownloadDirectoryHelper(TransferUtilityDownloadDirectoryRequest request)
{
CheckForBlockedArn(request.BucketName, "DownloadDirectory");
BaseCommand command = new DownloadDirectoryCommand(this._s3Client, request);
command.Execute();
}
#endregion
#region AbortMultipartUploads helper methods
private void AbortMultipartUploadsHelper(string bucketName, DateTime initiatedDate)
{
CheckForBlockedArn(bucketName, "AbortMultipartUploads");
BaseCommand command = new AbortMultipartUploadsCommand(this._s3Client, bucketName, initiatedDate);
command.Execute();
}
#endregion
#region Private Methods
static IAsyncResult beginOperation(BaseCommand command, AsyncCallback callback, object state)
{
Executer exe = new Executer(callback, state, command);
ThreadPool.QueueUserWorkItem(s => exe.Execute());
return exe.AsyncResult;
}
static object endOperation(IAsyncResult result)
{
TransferAsyncResult transferAsyncResult = result as TransferAsyncResult;
if (transferAsyncResult == null)
return null;
using (transferAsyncResult)
{
if (!transferAsyncResult.CompletedSynchronously)
{
WaitHandle.WaitAll(new WaitHandle[] { transferAsyncResult.AsyncWaitHandle });
}
if (transferAsyncResult.LastException != null)
{
AWSSDKUtils.PreserveStackTrace(transferAsyncResult.LastException);
throw transferAsyncResult.LastException;
}
return transferAsyncResult.Return;
}
}
#endregion
}
internal class Executer
{
TransferAsyncResult _asyncResult;
BaseCommand _command;
private Executer(TransferAsyncResult asyncResult, BaseCommand command)
{
this._asyncResult = asyncResult;
this._command = command;
}
internal Executer(AsyncCallback callback, object state, BaseCommand command)
: this(new TransferAsyncResult(callback, state), command)
{ }
internal void Execute()
{
try
{
this._command.Execute();
this._asyncResult.Return = this._command.Return;
}
catch (Exception e)
{
this._asyncResult.LastException = e;
}
finally
{
this._asyncResult.SignalWaitHandle();
if (this._asyncResult.Callback != null)
{
this._asyncResult.Callback(this._asyncResult);
}
}
}
internal TransferAsyncResult AsyncResult
{
get { return _asyncResult; }
}
}
internal class TransferAsyncResult : IAsyncResult, IDisposable
{
AsyncCallback _callback;
object _state;
bool _isComplete;
ManualResetEvent _waitHandle;
Exception _lastException;
object _return;
bool _disposed = false;
internal TransferAsyncResult(AsyncCallback callback, object state)
{
this._callback = callback;
this._state = state;
this._waitHandle = new ManualResetEvent(false);
}
public bool CompletedSynchronously
{
get { return false; }
}
public bool IsCompleted
{
get { return this._isComplete; }
}
public object AsyncState
{
get { return this._state; }
}
public WaitHandle AsyncWaitHandle
{
get { return this._waitHandle; }
}
internal void SignalWaitHandle()
{
this._isComplete = true;
this._waitHandle.Set();
}
internal AsyncCallback Callback
{
get { return this._callback; }
}
internal Exception LastException
{
get { return this._lastException; }
set { this._lastException = value; }
}
internal object Return
{
get { return this._return; }
set { this._return = value; }
}
#region Dispose Pattern Implementation
///
/// Implements the Dispose pattern
///
/// Whether this object is being disposed via a call to Dispose
/// or garbage collected.
protected virtual void Dispose(bool disposing)
{
if (!this._disposed)
{
if (disposing && _waitHandle != null)
{
_waitHandle.Close();
_waitHandle = null;
}
this._disposed = true;
}
}
///
/// Disposes of all managed and unmanaged resources.
///
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
}