@@ -15,10 +15,8 @@ namespace Ramstack.FileSystem.Amazon;
1515/// </summary>
1616internal sealed class S3UploadStream : Stream
1717{
18- private const long PartSize = 5 * 1024 * 1024 ;
19-
2018 // https://docs.aws.amazon.com/AmazonS3/latest/userguide/qfacts.html
21- private const long MaxPartSize = 5L * 1024 * 1024 * 1024 ;
19+ private const long PartSize = 5L * 1024 * 1024 ;
2220
2321 private readonly IAmazonS3 _client ;
2422 private readonly string _bucketName ;
@@ -230,28 +228,30 @@ private async ValueTask UploadPartAsync(CancellationToken cancellationToken)
230228 {
231229 _stream . Position = 0 ;
232230
233- do
231+ // https://docs.aws.amazon.com/AmazonS3/latest/userguide/qfacts.html
232+ // The maximum allowed part size is 5 GiB.
233+ // -----------------------------------------------------------------------------------
234+ // We don't need to worry about S3's 5 GiB part limit because:
235+ // 1. All Write/WriteAsync methods are inherently limited by Array.MaxLength (~2 GiB).
236+ // 2. The upload starts as soon as the buffer reaches MinPartSize (5 MiB).
237+ // Even if a single write matches Array.MaxLength, the data is
238+ // uploaded immediately, staying within AWS limits.
239+
240+ var request = new UploadPartRequest
234241 {
235- var remaining = _stream . Length - _stream . Position ;
236- var partSize = Math . Min ( remaining , MaxPartSize ) ;
237-
238- var request = new UploadPartRequest
239- {
240- BucketName = _bucketName ,
241- Key = _key ,
242- UploadId = _uploadId ,
243- PartNumber = _partETags . Count + 1 ,
244- InputStream = _stream ,
245- PartSize = partSize
246- } ;
247-
248- var response = await _client
249- . UploadPartAsync ( request , cancellationToken )
250- . ConfigureAwait ( false ) ;
251-
252- _partETags . Add ( new PartETag ( response ) ) ;
253- }
254- while ( _stream . Position < _stream . Length ) ;
242+ BucketName = _bucketName ,
243+ Key = _key ,
244+ UploadId = _uploadId ,
245+ PartNumber = _partETags . Count + 1 ,
246+ InputStream = _stream ,
247+ PartSize = _stream . Length
248+ } ;
249+
250+ var response = await _client
251+ . UploadPartAsync ( request , cancellationToken )
252+ . ConfigureAwait ( false ) ;
253+
254+ _partETags . Add ( new PartETag ( response ) ) ;
255255
256256 _stream . Position = 0 ;
257257 _stream . SetLength ( 0 ) ;
0 commit comments