Advertisement
Guest User

Untitled

a guest
Oct 20th, 2019
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.57 KB | None | 0 0
  1. public static class AwsS3Helper
  2. {
  3. public static async Task UploadObjectStreamAsync(
  4. this IAmazonS3 s3Client,
  5. Stream stream,
  6. UploadStreamToS3Request request)
  7. {
  8. async IAsyncEnumerable<UploadPartResponse> UploadAsync(string uploadId)
  9. {
  10. await foreach (var (partStream, index, isLast) in SplitPartsFromStream(stream, request.ParSize))
  11. {
  12. var partRequest = new UploadPartRequest
  13. {
  14. BucketName = request.Bucket,
  15. Key = request.Key,
  16. UploadId = uploadId,
  17. InputStream = partStream,
  18. PartNumber = index,
  19. IsLastPart = isLast
  20. };
  21. yield return await s3Client.UploadPartAsync(partRequest);
  22. await partStream.DisposeAsync();
  23. }
  24. }
  25.  
  26. var initRequest = new InitiateMultipartUploadRequest
  27. {
  28. BucketName = request.Bucket,
  29. Key = request.Key
  30. };
  31.  
  32. if (!string.IsNullOrEmpty(request.DownloadFileName))
  33. initRequest.Headers.ContentDisposition = $"attachment; filename={request.DownloadFileName}";
  34.  
  35. if (!string.IsNullOrEmpty(request.ContentType))
  36. initRequest.Headers.ContentType = request.ContentType;
  37.  
  38. var initResponse = await s3Client.InitiateMultipartUploadAsync(initRequest);
  39.  
  40. if (request.ParSize < 1024 * 1024 * 5)
  41. throw new ArgumentException($"{nameof(request.ParSize)} must be greater than 5MB");
  42.  
  43. var uploadAsync = await UploadAsync(initResponse.UploadId).ToListAsync();
  44. var uploadRequest = new CompleteMultipartUploadRequest
  45. {
  46. BucketName = request.Bucket,
  47. Key = request.Key,
  48. UploadId = initResponse.UploadId
  49. };
  50. uploadRequest.AddPartETags(uploadAsync);
  51.  
  52. await s3Client.CompleteMultipartUploadAsync(uploadRequest);
  53. }
  54.  
  55. private static async IAsyncEnumerable<(MemoryStream stream, int index, bool isLast)> SplitPartsFromStream(
  56. Stream inputStream,
  57. int partSize)
  58. {
  59. inputStream.Position = 0;
  60. var index = 1;
  61. for (var remainingBytes = inputStream.Length; remainingBytes > 0; remainingBytes -= partSize)
  62. {
  63. var isLast = remainingBytes < partSize;
  64. var buffer = isLast
  65. ? new byte[remainingBytes]
  66. : new byte[partSize];
  67.  
  68. await inputStream.ReadAsync(buffer, 0, buffer.Length);
  69. yield return (new MemoryStream(buffer), index, isLast);
  70. index++;
  71. }
  72. }
  73.  
  74. private static async Task<IList<T>> ToListAsync<T>(this IAsyncEnumerable<T> asyncEnumerable)
  75. {
  76. var list = new List<T>();
  77. await foreach (var item in asyncEnumerable) list.Add(item);
  78. return list;
  79. }
  80. }
  81.  
  82. public class UploadStreamToS3Request
  83. {
  84. public string Bucket { get; set; }
  85.  
  86. public string Key { get; set; }
  87.  
  88. public int ParSize { get; set; } = 1024 * 1024 * 5;
  89.  
  90. public string DownloadFileName { get; set; }
  91.  
  92. public string ContentType { get; set; }
  93. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement