s3 File Uploading is so slow C# - c#

I'm using the transferUtility class to upload files into S3 using input stream in .NET. The problem is, uploading a file of 4MB takes around a minute. I tried both transferUtility.Upload and S3Client.PutObject and the upload time didn't seem to change. The code is below:
WebRequest.DefaultWebProxy = null;
this.S3Client = new Amazon.S3.AmazonS3Client(accessKeyId, secretAccessKey, endPoint);
this.transferUtility = new TransferUtility(this.S3Client);
Amazon.S3.Transfer.TransferUtilityUploadRequest transferRequest = new TransferUtilityUploadRequest();
transferRequest.BucketName = s3Bucket;
transferRequest.CannedACL = Amazon.S3.S3CannedACL.PublicRead;
transferRequest.InputStream = (Stream)fileStream;
transferRequest.Key = newFileName;
transferRequest.Headers.Expires = new DateTime(2020, 1, 1);
this.transferUtility.Upload(transferRequest);
Any help would be appreciated.
Thank you,

I found that this is happening because of an uploading the file stream to the application server takes a very long time.

This is likely also due to the C# SDK MD5sum'ing every chunk it uploads (CPU performance hit and thus slows down the upload while an MD5Sum is computed).
See https://github.com/aws/aws-sdk-net/issues/832#issuecomment-383756520 for workaround.

Related

How do I resize an image from Azure while also considering the disk-cache?

I'm currently trying to generate a PDF report on my website with a bunch of images. All of those images are stored in an Azure blob storage in their original size.
Throughout the website I'm using the ImageResizer middleware with the Azure and DiskCache plugins and they work perfectly, however it seems that for the PDF report I have to use the ImageResizer API which will only accept a Stream, Bitmap or a path as input.
My current implementation technically works (which is downloading the blob and providing the stream), but it's very slow.
Is there a way to call the API while utilizing the disk-cache too? I've tried to provide paths like /azure/someblob.jpg but it doesn't work.
Edit: as per Natahniel's suggestion, I came up with this solution (for use with iTextSharp):
private Image GetImageResized(string path) {
var request = HttpContext.Current.Request.Url;
var uri = new Uri(request.Scheme + "://" + request.Authority + "/" + path, UriKind.Absolute);
Stream dest = null;
using (var client = new WebClient()) {
dest = new MemoryStream(client.DownloadData(uri));
}
return iTextSharp.text.Image.GetInstance(dest);
}
The path in this case would be something like azure/mycontainer/someblob.jpg?height=500
It should be something like /azure/path/to/document.pdf?format=png&page=1
Disk caching of Azure-provided PDF blobs is supported for the HTTP API, which would be best for this situation.

Download many files async from Http

I have a http server and I need to download files from that server to my computer every time I launch the app on my PC, I need to download about five thousand files and each of them are about 1-2 kb. Here is the code that I use for it:
WebClient[][] wbc = new WebClient[1][];
for(int file=0 ; file < myfilecount ; file++)
{
wbc[0][film] = new WebClient();
wbc[0][film].Credentials = new NetworkCredential(username, password);
wbc[0][film].DownloadFileCompleted += Form4_DownloadFileCompleted;
wbc[0][film].DownloadFileTaskAsync("http://MYIPADDRESS/File" + file.ToString(), databaselocation + "\\File" + file.toString());
}
When I do this it downloads files into ram in about 3 sec. But it takes about one minute to write them to my hdd. Is there any faster way to download those files to my HDD?
Also I am getting the information about the count of those files by a file that I write, so is there any better way to download all of them?
I agree if this is required every time you launch the app on your pc you should rethink the process. But then again, I don't completely know your circumstances. That aside, you can make a queued collection of request tasks and wait for them all concurrently:
var requestTasks = Enumerable.Range(0, myFileCount).Select(i => {
var webClient = new WebClient
{
Credentials = new NetworkCredential(username, password),
DownloadFileCompleted += Form4_DownloadFileCompleted
};
return webClient.DownloadFileTaskAsync("http://MYIPADDRESS/File" + i.ToString(), Path.Combine(databaselocation, "file" + i.ToString()));
});
await Task.WhenAll(requestTasks);
Also I believe WebClient is limited to the number of requests that can be made concurrently to the same host, you can configure this by using ServicePointManager:
ServicePointManager.DefaultConnectionLimit = carefullyCalculatedNumber;
I'd be careful with the number of connections allowed, too high of a limit can also become a problem. Hope this helps.

File downloaded from gdrive is corrupted

I have a problem downloading file from gdrive
I am using this code
DriveService service = new DriveService();
var Stream = service.HttpClient.GetStreamAsync("https://drive.google.com/open?id=blablabla");
var result = Stream.Result;
using (var fileStream = System.IO.File.Create("MyFile.exe"))
{
result.CopyTo(fileStream);
}
But I am getting size of 103kB in MyFile.exe, and it has 800 kB.
I suspect that I am not getting download url right, as I right click on the file I want to download and get shareable link in this format: https://drive.google.com/open?id=blablaid
According to www.labnol.org/internet/direct-links-for-google-drive/28356/ the Google Drive download link is https://docs.google.com/uc?export=download&id=[FILE_ID].
Otherwise you could also look at the Google Drive REST API (developers.google.com/drive/v3/web/manage-downloads).

RestSharp - Output file download result in browser

I'm quite new to using RestSharp and I've got a question that I can't find an answer to here on SO.
I've have this situation where I must download a csv-file and output the file directly in the browser. The following code illustrates how to download a file and save it to a certain path on disc.
string tempFile = Path.GetTempFileName();
using (var writer = File.OpenWrite(tempFile))
{
var client = new RestClient(baseUrl);
var request = new RestRequest("Assets/LargeFile.7z");
request.ResponseWriter = (responseStream) => responseStream.CopyTo(writer);
var response = client.DownloadData(request);
}
I want to download the csv-file and directly output the result as a download file in the browser. You know, like in Chrome the file you download will be displayed in the left bottom corner of your browser.
Can this be done using RestSharp? And if so, how? Got an example? Please share it. ;-)
Thanx!

.Net web client fails downloading after 2 GB from S3

I'm using the web client object to download a file like so:
strm = Client.OpenRead(url);
strm.ReadTimeout = 30000;
bool bFirst = true;
while ((read = strm.Read(buf, 0, 2000)) > 0)
{
fout.Write(buf, 0, read);
}
Where the url points to an S3 bucket. In some cases the download fails with a timeout at exactly 2 GB. Is this a network issue, or is there something I could change in the code?
Any ideas appreciated.
I believe WebClient will read the file into memory, and you're probably running into process size limitations.
What you'll want to use is WebClient.DownloadFile
I believe this will work better for you!

Categories