Reputation: 12127
I am trying to save files to a S3 bucket using the AWSSDK.S3 nuget package. My code is in F#, but answers in C# would work too.
I have a series of files I want to organize by folder. From what I understand, there is not really a folder structure in the S3 buckets, but folders are rather 'keys' which are part of the filename. I could be wrong, but that's my understanding at this point.
The code is taking crypto coin data and making one file a day, per coin. This was working until I wanted to make one folder per coin.
Filenames have the following format: "coinname-YYMMDD.csv', for example: "BTCUSDT-20200820.csv'. and I want a structure like:
coin1/
coin1-20200819.csv
coin1-20200820.csv
coin2/
coin2-20200819.csv
coin2-20200820.csv
From the documentation, I need to set the folder as a 'key', so here is the code:
// upload a file
let uploadFile (filename: string) =
// create the key
let coinName = Path.GetFileName(filename).Split('-').[0]
let keyName = Path.Combine(coinName, filename)
// create the send request
let putObjectRequest = Amazon.S3.Model.PutObjectRequest()
putObjectRequest.FilePath <- filename
putObjectRequest.Key <- keyName
putObjectRequest.BucketName <- bucketName
putObjectRequest.CannedACL <- S3CannedACL.PublicRead
putObjectRequest.StorageClass <- S3StorageClass.IntelligentTiering
putObjectRequest.ContentType <- "text/csv"
// send the object
let response =
s3client.PutObjectAsync(putObjectRequest)
|> Async.AwaitTask
|> Async.RunSynchronously
// DEBUG OUTPUT
printfn "trying to save %s" keyName
printfn "object request: %s" (putObjectRequest |> JsonConvert.SerializeObject)
printfn "response: %s" (response |> JsonConvert.SerializeObject)
// handle the response
match response.HttpStatusCode with
| HttpStatusCode.OK -> Ok()
| _ -> let message = sprintf "error uploading file %s to S3: %s" filename (response.ToString())
Error(message)
The debug output shows this:
trying to save /app/leechdata/ATOMUSDT/ATOMUSDT-20200819.csv object request: {"CannedACL":{"Value":"public-read"},"InputStream":null,"FilePath":"/app/leechdata/ATOMUSDT/ATOMUSDT-20200819.csv","ContentBody":null,"AutoCloseStream":true,"AutoResetStreamPosition":true,"UseChunkEncoding":true,"BucketName":"sunnybot-cap ture","Headers":{"Count":1,"Keys":["Content-Type"],"CacheControl":null,"ContentDisposition":null,"ContentEncoding":null,"ContentLength":-1,"ContentMD5":null,"ContentType":"text/csv","ExpiresUtc":null,"Expires":null},"Metadata":{"Count":0,"Keys":[]},"Key" :"/app/leechdata/ATOMUSDT/ATOMUSDT-20200819.csv","ServerSideEncryptionMethod":null,"ServerSideEncryptionCustomerMethod":null,"ServerSideEncryptionCustomerProvidedKey":null,"ServerSideEncryptionCustomerProvidedKeyMD5":null,"ServerSideEncryptionKeyManageme ntServiceKeyId":null,"ServerSideEncryptionKeyManagementServiceEncryptionContext":null,"StorageClass":{"Value":"INTELLIGENT_TIERING"},"ObjectLockLegalHoldStatus":null,"ObjectLockMode":null,"ObjectLockRetainUntilDate":"0001-01-01T00:00:00","WebsiteRedirect Location":null,"StreamTransferProgress":null,"ContentType":"text/csv","MD5Digest":null,"RequestPayer":null,"TagSet":[],"Grants":[]} response: {"Expiration":null,"ServerSideEncryptionMethod":null,"ETag":""6a614845e94ffa3fc1bfb8aad40bdb5b"","VersionId":null,"ServerSideEncryptionKeyManagementServiceKeyId":null,"ServerSideEncryptionCustomerMethod":null,"ServerSideEncryptionCustomerProv idedKeyMD5":null,"ServerSideEncryptionKeyManagementServiceEncryptionContext":null,"RequestCharged":null,"ResponseMetadata":{"RequestId":"81892F3E28F07562","Metadata":{"x-amz-id-2":"/mTevk7iATTIKlvIs6eGGc3QK9+rHdzgPu6SzZ36eNfEzyjOS2BjXnEazTchL6z8P9kqU+eZJ N8="}},"ContentLength":0,"HttpStatusCode":200}
so, it looks like everything is fine, but the files do not appear! if I don't specify the Key field, all the files get properly uploaded, without a folder.
What am I missing?
Upvotes: 0
Views: 2789
Reputation: 696
To upload files to S3, I suggest to use TransferUtility
, your key should contain both "folder" and "filename", e.g. coin1/coin1-20200819.csv
. The TransferUtility.UploadAsync
method would take 3 arguments:
@"C:\coin1-20200819.csv"
crypto
"coin1/coin1-20200819.csv"
Your code to upload a file would be something like thislet fileTransferUtil = new TransferUtility( s3client ) // create a transfer utility
fileTransferUtil.UploadAsync(@"C:\coin1-20200819.csv", "crypto", "coin1/coin1-20200819.csv" ) |> Async.AwaitTask |> Async.RunSynchronously
Upvotes: 2