Pertanyaan Bagaimana cara mengunggah file ke Amazon S3 (SDK resmi) yang lebih besar dari 5 MB (kira-kira)?


Saya menggunakan versi terbaru SDK Amazon S3 resmi (1.0.14.1) untuk membuat alat cadangan. Sejauh ini semuanya berjalan dengan benar jika ukuran file yang saya unggah di bawah 5 MB, tetapi ketika salah satu file di atas 5 MB, unggahan gagal dengan pengecualian berikut:

System.Net.WebException: Permintaan   dibatalkan: Permintaan dibatalkan.   ---> System.IO.IOException: Tidak dapat menutup aliran sampai semua byte berada   tertulis. di   System.Net.ConnectStream.CloseInternal (Boolean   internalCall, Boolean aborting) ---   Akhir jejak tumpukan pengecualian batin ---   di   Amazon.S3.AmazonS3Client.ProcessRequestError (String   actionName, permintaan HttpWebRequest,   WebException kami, HttpWebResponse   errorResponse, String requestAddr,   WebHeaderCollection & respHdrs, Ketik t)   di   Amazon.S3.AmazonS3Client.Invoke [T] (S3Request   userRequest) di   Amazon.S3.AmazonS3Client.PutObject (PutObjectRequest   permintaan) di   BackupToolkit.S3Module.UploadFile (String   sourceFileName, String   destinationFileName) di   W: \ code \ AutoBackupTool \ BackupToolkit \ S3Module.cs: line   88 di   BackupToolkit.S3Module.UploadFiles (String   sourceDirectory) di   W: \ code \ AutoBackupTool \ BackupToolkit \ S3Module.cs: line   108

Catatan: 5 MB kira-kira batas kegagalan, bisa sedikit lebih rendah atau lebih tinggi

Saya berasumsi bahwa koneksi sudah waktunya habis dan aliran secara otomatis ditutup sebelum unggahan file selesai.

Saya sudah mencoba mencari cara untuk mengatur batas waktu yang lama (tetapi saya juga tidak dapat menemukan opsi tersebut AmazonS3 atau AmazonS3Config).

Ada gagasan tentang cara meningkatkan time-out (seperti pengaturan luas aplikasi yang dapat saya gunakan) atau tidak terkait dengan masalah timeout?


Kode:

var s3Client = AWSClientFactory.CreateAmazonS3Client(AwsAccessKey, AwsSecretKey);

var putObjectRequest = new PutObjectRequest {

    BucketName            = Bucket,
    FilePath              = sourceFileName,
    Key                   = destinationFileName,
    MD5Digest             = md5Base64,
    GenerateMD5Digest     = true
};

using (var upload = s3Client.PutObject(putObjectRequest)) {  }

36
2017-10-06 10:11


asal


Jawaban:


Jawaban yang diperbarui:

Saya baru saja memperbarui salah satu proyek saya yang menggunakan Amazon AWS .NET SDK (ke versi 1.4.1.0) dan dalam versi ini ada dua perbaikan yang tidak ada ketika saya menulis jawaban asli di sini.

  1. Anda sekarang dapat mengatur Timeout untuk -1 untuk memiliki batas waktu tak terbatas untuk operasi put.
  2. Sekarang ada properti ekstra PutObjectRequest bernama ReadWriteTimeout yang dapat diatur (dalam milidetik) ke batas waktu pada tingkat aliran baca / tulis yang berlawanan dengan tingkat operasi keseluruhan.

Jadi kode saya sekarang terlihat seperti ini:

var putObjectRequest = new PutObjectRequest {

    BucketName            = Bucket,
    FilePath              = sourceFileName,
    Key                   = destinationFileName,
    MD5Digest             = md5Base64,
    GenerateMD5Digest     = true,
    Timeout               = -1,
    ReadWriteTimeout      = 300000     // 5 minutes in milliseconds
};

Jawaban asli:


Saya berhasil mencari jawabannya ...

Sebelum memposting pertanyaan yang saya jelajahi AmazonS3 dan AmazonS3Config tapi tidak PutObjectRequest.

Dalam PutObjectRequest ada sebuah Timeout properti (ditetapkan dalam milidetik). Saya telah berhasil menggunakan ini untuk mengunggah file yang lebih besar (catatan: menyetelnya ke 0 tidak menghapus batas waktu, Anda perlu menentukan jumlah milidetik positif ... Saya sudah pergi selama 1 jam).

Ini berfungsi dengan baik:

var putObjectRequest = new PutObjectRequest {

    BucketName            = Bucket,
    FilePath              = sourceFileName,
    Key                   = destinationFileName,
    MD5Digest             = md5Base64,
    GenerateMD5Digest     = true,
    Timeout               = 3600000
};

42
2017-10-06 10:24



Saya telah mengalami masalah yang serupa dengan ini dan mulai menggunakan kelas TransferUtility untuk melakukan multi-bagian upload.

Saat ini kode ini berfungsi. Saya memiliki masalah ketika batas waktu ditetapkan terlalu rendah sekalipun!

                var request = new TransferUtilityUploadRequest()
                .WithBucketName(BucketName)
                .WithFilePath(sourceFile.FullName)
                .WithKey(key)
                .WithTimeout(100 * 60 * 60 * 1000)
                .WithPartSize(10 * 1024 * 1024)
                .WithSubscriber((src, e) =>
                {
                    Console.CursorLeft = 0;
                    Console.Write("{0}: {1} of {2}    ", sourceFile.Name, e.TransferredBytes, e.TotalBytes);
                });
            utility.Upload(request);

Saat saya mengetik ini, saya memiliki upload 4GB dan sudah lebih dari sebelumnya!


10
2018-04-02 06:58



AWS SDK untuk .NET dua API utama untuk bekerja dengan Amazon S3.Both dapat mengunggah file besar dan kecil pada S3.

1. API level rendah:

API level rendah menggunakan pola yang sama yang digunakan untuk layanan lain   API tingkat rendah di SDK. Ada objek klien yang disebut    AmazonS3Client yang mengimplementasikan antarmuka IAmazonS3.Ini berisi    metode untuk masing-masing operasi layanan yang diekspos oleh S3.

Namespace: Amazon.S3, Amazon.S3.Model

// Step 1 : 
AmazonS3Config s3Config = new AmazonS3Config();
s3Config.RegionEndpoint = GetRegionEndPoint();

// Step 2 :
using(var client = new AmazonS3Client(My_AWSAccessKey, My_AWSSecretKey, s3Config) )
{
    // Step 3 :
    PutObjectRequest request = new PutObjectRequest();
    request.Key = My_key;
    request.InputStream = My_fileStream;
    request.BucketName = My_BucketName;

    // Step 4 : Finally place object to S3
    client.PutObject(request);
}

2. TransferUtility:  (Saya akan merekomendasikan menggunakan API ini)

TransferUtility berjalan di atas API level rendah. Untuk menempatkan dan   mendapatkan objek ke dalam S3, Ini adalah sebuah   antarmuka sederhana untuk menangani penggunaan S3 yang paling umum. Yang terbesar   manfaat datang dengan meletakkan benda. Misalnya, TransferUtility   mendeteksi apakah file berukuran besar dan beralih ke mode unggahan multiguna.

Namespace: Amazon.S3.Transfer

// Step 1 : Create "Transfer Utility" (replacement of old "Transfer Manager")
TransferUtility fileTransferUtility =
     new TransferUtility(new AmazonS3Client(Amazon.RegionEndpoint.USEast1));

// Step 2 : Create Request object
TransferUtilityUploadRequest uploadRequest =
    new TransferUtilityUploadRequest
    {
        BucketName = My_BucketName,
        FilePath = My_filePath, 
        Key = My_keyName
    };

// Step 3 : Event Handler that will be automatically called on each transferred byte 
uploadRequest.UploadProgressEvent +=
    new EventHandler<UploadProgressArgs>
        (uploadRequest_UploadPartProgressEvent);

static void uploadRequest_UploadPartProgressEvent(object sender, UploadProgressArgs e)
{    
    Console.WriteLine("{0}/{1}", e.TransferredBytes, e.TotalBytes);
}

// Step 4 : Hit upload and send data to S3
fileTransferUtility.Upload(uploadRequest);

7
2017-07-13 10:44



Nick Randell telah mendapatkan ide yang tepat untuk ini, lebih lanjut ke posnya di sini adalah contoh lain dengan beberapa alternatif penanganan acara, dan metode untuk mendapatkan persentase selesai untuk file yang diunggah:

        private static string WritingLargeFile(AmazonS3 client, int mediaId, string bucketName, string amazonKey, string fileName, string fileDesc, string fullPath)
    {
        try
        {

            Log.Add(LogTypes.Debug, mediaId, "WritingLargeFile: Create TransferUtilityUploadRequest");
            var request = new TransferUtilityUploadRequest()
                .WithBucketName(bucketName)
                .WithKey(amazonKey)
                .WithMetadata("fileName", fileName)
                .WithMetadata("fileDesc", fileDesc)
                .WithCannedACL(S3CannedACL.PublicRead)
                .WithFilePath(fullPath)
                .WithTimeout(100 * 60 * 60 * 1000) //100 min timeout
                .WithPartSize(5 * 1024 * 1024); // Upload in 5MB pieces 

            request.UploadProgressEvent += new EventHandler<UploadProgressArgs>(uploadRequest_UploadPartProgressEvent);

            Log.Add(LogTypes.Debug, mediaId, "WritingLargeFile: Create TransferUtility");
            TransferUtility fileTransferUtility = new TransferUtility(ConfigurationManager.AppSettings["AWSAccessKey"], ConfigurationManager.AppSettings["AWSSecretKey"]);

            Log.Add(LogTypes.Debug, mediaId, "WritingLargeFile: Start Upload");
            fileTransferUtility.Upload(request);

            return amazonKey;
        }
        catch (AmazonS3Exception amazonS3Exception)
        {
            if (amazonS3Exception.ErrorCode != null &&
                (amazonS3Exception.ErrorCode.Equals("InvalidAccessKeyId") ||
                amazonS3Exception.ErrorCode.Equals("InvalidSecurity")))
            {
                Log.Add(LogTypes.Debug, mediaId, "Please check the provided AWS Credentials.");
            }
            else
            {
                Log.Add(LogTypes.Debug, mediaId, String.Format("An error occurred with the message '{0}' when writing an object", amazonS3Exception.Message));
            }
            return String.Empty; //Failed
        }
    }

    private static Dictionary<string, int> uploadTracker = new Dictionary<string, int>();
    static void uploadRequest_UploadPartProgressEvent(object sender, UploadProgressArgs e)
    {
        TransferUtilityUploadRequest req = sender as TransferUtilityUploadRequest;          
        if (req != null)
        {
            string fileName = req.FilePath.Split('\\').Last();
            if (!uploadTracker.ContainsKey(fileName))
                uploadTracker.Add(fileName, e.PercentDone);

            //When percentage done changes add logentry:
            if (uploadTracker[fileName] != e.PercentDone)
            {
                uploadTracker[fileName] = e.PercentDone;
                Log.Add(LogTypes.Debug, 0, String.Format("WritingLargeFile progress: {1} of {2} ({3}%) for file '{0}'", fileName, e.TransferredBytes, e.TotalBytes, e.PercentDone));
            }
        }

    }

    public static int GetAmazonUploadPercentDone(string fileName)
    {
        if (!uploadTracker.ContainsKey(fileName))
            return 0;

        return uploadTracker[fileName];
    }

6
2018-01-06 20:04



lihat topik ini di sini Cara mengunggah file ke amazon S3 super mudah menggunakan c # termasuk proyek demo untuk diunduh. itu adalah level tinggi menggunakan AWS sdk .net 3.5 (dan lebih tinggi) dapat digunakan dengan menggunakan kode berikut:

    // preparing our file and directory names
        string fileToBackup = @"d:\mybackupFile.zip" ; // test file
        string myBucketName = "mys3bucketname"; //your s3 bucket name goes here
        string s3DirectoryName = "justdemodirectory";
        string s3FileName = @"mybackupFile uploaded in 12-9-2014.zip";
        AmazonUploader myUploader = new AmazonUploader();
        myUploader.sendMyFileToS3(fileToBackup, myBucketName, s3DirectoryName, s3FileName);

1
2017-09-14 17:07