我有一个REST API,它必须从AWS服务器中的远程URL获取文件。 该文件已下载,但当我尝试打开它时,它没有显示任何内容,如损坏。
没有异常被抛出
代码就是这个
[HttpPost] [Route("api/[controller]/UploadFileToAzureStorage")] public async Task<IActionResult> GetFile([FromBody]PDF urlPdf) { string localFilePath = CreateTemporaryFile(urlPdf.urlPDF); // Create storage account CloudStorageAccount storageAccount = CloudStorageAccount.Parse(StorageAccount); // Create a blob client. CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); // Get a reference to a container named "mycontainer." CloudBlobContainer container = blobClient.GetContainerReference(UploaderStorage.Container); // Get a reference to a blob named "myblob". CloudBlockBlob blockBlob = container.GetBlockBlobReference("myblob"); // Create or overwrite the "myblob" blob with the contents of a local file // named "myfile". using (var fileStream = System.IO.File.OpenRead(localFilePath)) { await blockBlob.UploadFromStreamAsync(fileStream); } return Ok(); } /// <summary> /// Creates temporary file /// </summary> /// <param name="urlPdf">PDF URL</param> /// <returns>Returns path of the new file</returns> private string CreateTemporaryFile(string urlPdf) { Uri uri = new Uri(urlPdf); string filename = default(string); //if (uri.IsFile) //{ filename = System.IO.Path.GetFileName(uri.LocalPath); //} try { using (var client = new HttpClient()) { using (HttpResponseMessage response = client.GetAsync(urlPdf, HttpCompletionOption.ResponseHeadersRead).Result) { response.EnsureSuccessStatusCode(); using (Stream contentStream = response.Content.ReadAsStreamAsync().Result, fileStream = new FileStream(@"\\pc030\TemporaryPDF\"+ filename, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true)) { var buffer = new byte[8192]; var isMoreToRead = true; do { var read = contentStream.ReadAsync(buffer, 0, buffer.Length).Result; if (read == 0) { isMoreToRead = false; } else { fileStream.WriteAsync(buffer, 0, read); } } while (isMoreToRead); } } } return @"\\pc030\TemporaryPDF\" + filename; } catch(Exception ex) { throw ex; } }I have a REST API which must get a file from a remote URL in AWS servers. The file is downloaded but when I try to open it, it shows nothing, like corrupted.
No exceptions are thrown
the code is this
[HttpPost] [Route("api/[controller]/UploadFileToAzureStorage")] public async Task<IActionResult> GetFile([FromBody]PDF urlPdf) { string localFilePath = CreateTemporaryFile(urlPdf.urlPDF); // Create storage account CloudStorageAccount storageAccount = CloudStorageAccount.Parse(StorageAccount); // Create a blob client. CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); // Get a reference to a container named "mycontainer." CloudBlobContainer container = blobClient.GetContainerReference(UploaderStorage.Container); // Get a reference to a blob named "myblob". CloudBlockBlob blockBlob = container.GetBlockBlobReference("myblob"); // Create or overwrite the "myblob" blob with the contents of a local file // named "myfile". using (var fileStream = System.IO.File.OpenRead(localFilePath)) { await blockBlob.UploadFromStreamAsync(fileStream); } return Ok(); } /// <summary> /// Creates temporary file /// </summary> /// <param name="urlPdf">PDF URL</param> /// <returns>Returns path of the new file</returns> private string CreateTemporaryFile(string urlPdf) { Uri uri = new Uri(urlPdf); string filename = default(string); //if (uri.IsFile) //{ filename = System.IO.Path.GetFileName(uri.LocalPath); //} try { using (var client = new HttpClient()) { using (HttpResponseMessage response = client.GetAsync(urlPdf, HttpCompletionOption.ResponseHeadersRead).Result) { response.EnsureSuccessStatusCode(); using (Stream contentStream = response.Content.ReadAsStreamAsync().Result, fileStream = new FileStream(@"\\pc030\TemporaryPDF\"+ filename, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true)) { var buffer = new byte[8192]; var isMoreToRead = true; do { var read = contentStream.ReadAsync(buffer, 0, buffer.Length).Result; if (read == 0) { isMoreToRead = false; } else { fileStream.WriteAsync(buffer, 0, read); } } while (isMoreToRead); } } } return @"\\pc030\TemporaryPDF\" + filename; } catch(Exception ex) { throw ex; } }最满意答案
response.Content.ReadAsStreamAsync().Result和contentStream.ReadAsync(buffer, 0, buffer.Length).Result是一个等待在代码中关闭的死锁炸弹。
除非您完全理解这样做的含义,否则永远不要在UI代码或服务器代码中等待Task.Result 。
服务器和UI都使用特殊的SynchronizationContext ,将异步延迟调度回调用线程。 当同一个线程已挂起,等待Result ,一切都可以锁定。
阅读和摘要:
https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
您的CreateTemporaryFile方法应标记为async ,您应该await这些调用。
那么,对你的问题。 你正在调用fileStream.WriteAsync(buffer, 0, read)而不await Task的完成。 在(至少)最后一次写入时,将在写入完成之前处理流,并产生可预测的结果。
正确采用async或根本不使用它。 没有中途宿舍。
response.Content.ReadAsStreamAsync().Result and contentStream.ReadAsync(buffer, 0, buffer.Length).Result are a deadlock-bomb waiting to go off in your code.
Never block by waiting on Task.Result in UI code or server code unless you fully understand the implications of doing so.
Both server and UI use a special SynchronizationContext that schedules the async continuation back to the calling thread. When that same thread is already hung, waiting for Result, everything can lock-up.
Read and digest:
https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
Your CreateTemporaryFile method should be marked async and you should be awaiting those calls.
So, to your problem. You're calling fileStream.WriteAsync(buffer, 0, read) without awaiting the Task's completion. On the (at least) last write, the stream will be disposed before the write is complete, with predicable results.
Adopt async properly or don't use it at all. There's no half-way house.
通过c#下载时,PDF文件已损坏(PDF File is corrupted when dowloaded via c#)我有一个REST API,它必须从AWS服务器中的远程URL获取文件。 该文件已下载,但当我尝试打开它时,它没有显示任何内容,如损坏。
没有异常被抛出
代码就是这个
[HttpPost] [Route("api/[controller]/UploadFileToAzureStorage")] public async Task<IActionResult> GetFile([FromBody]PDF urlPdf) { string localFilePath = CreateTemporaryFile(urlPdf.urlPDF); // Create storage account CloudStorageAccount storageAccount = CloudStorageAccount.Parse(StorageAccount); // Create a blob client. CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); // Get a reference to a container named "mycontainer." CloudBlobContainer container = blobClient.GetContainerReference(UploaderStorage.Container); // Get a reference to a blob named "myblob". CloudBlockBlob blockBlob = container.GetBlockBlobReference("myblob"); // Create or overwrite the "myblob" blob with the contents of a local file // named "myfile". using (var fileStream = System.IO.File.OpenRead(localFilePath)) { await blockBlob.UploadFromStreamAsync(fileStream); } return Ok(); } /// <summary> /// Creates temporary file /// </summary> /// <param name="urlPdf">PDF URL</param> /// <returns>Returns path of the new file</returns> private string CreateTemporaryFile(string urlPdf) { Uri uri = new Uri(urlPdf); string filename = default(string); //if (uri.IsFile) //{ filename = System.IO.Path.GetFileName(uri.LocalPath); //} try { using (var client = new HttpClient()) { using (HttpResponseMessage response = client.GetAsync(urlPdf, HttpCompletionOption.ResponseHeadersRead).Result) { response.EnsureSuccessStatusCode(); using (Stream contentStream = response.Content.ReadAsStreamAsync().Result, fileStream = new FileStream(@"\\pc030\TemporaryPDF\"+ filename, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true)) { var buffer = new byte[8192]; var isMoreToRead = true; do { var read = contentStream.ReadAsync(buffer, 0, buffer.Length).Result; if (read == 0) { isMoreToRead = false; } else { fileStream.WriteAsync(buffer, 0, read); } } while (isMoreToRead); } } } return @"\\pc030\TemporaryPDF\" + filename; } catch(Exception ex) { throw ex; } }I have a REST API which must get a file from a remote URL in AWS servers. The file is downloaded but when I try to open it, it shows nothing, like corrupted.
No exceptions are thrown
the code is this
[HttpPost] [Route("api/[controller]/UploadFileToAzureStorage")] public async Task<IActionResult> GetFile([FromBody]PDF urlPdf) { string localFilePath = CreateTemporaryFile(urlPdf.urlPDF); // Create storage account CloudStorageAccount storageAccount = CloudStorageAccount.Parse(StorageAccount); // Create a blob client. CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); // Get a reference to a container named "mycontainer." CloudBlobContainer container = blobClient.GetContainerReference(UploaderStorage.Container); // Get a reference to a blob named "myblob". CloudBlockBlob blockBlob = container.GetBlockBlobReference("myblob"); // Create or overwrite the "myblob" blob with the contents of a local file // named "myfile". using (var fileStream = System.IO.File.OpenRead(localFilePath)) { await blockBlob.UploadFromStreamAsync(fileStream); } return Ok(); } /// <summary> /// Creates temporary file /// </summary> /// <param name="urlPdf">PDF URL</param> /// <returns>Returns path of the new file</returns> private string CreateTemporaryFile(string urlPdf) { Uri uri = new Uri(urlPdf); string filename = default(string); //if (uri.IsFile) //{ filename = System.IO.Path.GetFileName(uri.LocalPath); //} try { using (var client = new HttpClient()) { using (HttpResponseMessage response = client.GetAsync(urlPdf, HttpCompletionOption.ResponseHeadersRead).Result) { response.EnsureSuccessStatusCode(); using (Stream contentStream = response.Content.ReadAsStreamAsync().Result, fileStream = new FileStream(@"\\pc030\TemporaryPDF\"+ filename, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true)) { var buffer = new byte[8192]; var isMoreToRead = true; do { var read = contentStream.ReadAsync(buffer, 0, buffer.Length).Result; if (read == 0) { isMoreToRead = false; } else { fileStream.WriteAsync(buffer, 0, read); } } while (isMoreToRead); } } } return @"\\pc030\TemporaryPDF\" + filename; } catch(Exception ex) { throw ex; } }最满意答案
response.Content.ReadAsStreamAsync().Result和contentStream.ReadAsync(buffer, 0, buffer.Length).Result是一个等待在代码中关闭的死锁炸弹。
除非您完全理解这样做的含义,否则永远不要在UI代码或服务器代码中等待Task.Result 。
服务器和UI都使用特殊的SynchronizationContext ,将异步延迟调度回调用线程。 当同一个线程已挂起,等待Result ,一切都可以锁定。
阅读和摘要:
https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
您的CreateTemporaryFile方法应标记为async ,您应该await这些调用。
那么,对你的问题。 你正在调用fileStream.WriteAsync(buffer, 0, read)而不await Task的完成。 在(至少)最后一次写入时,将在写入完成之前处理流,并产生可预测的结果。
正确采用async或根本不使用它。 没有中途宿舍。
response.Content.ReadAsStreamAsync().Result and contentStream.ReadAsync(buffer, 0, buffer.Length).Result are a deadlock-bomb waiting to go off in your code.
Never block by waiting on Task.Result in UI code or server code unless you fully understand the implications of doing so.
Both server and UI use a special SynchronizationContext that schedules the async continuation back to the calling thread. When that same thread is already hung, waiting for Result, everything can lock-up.
Read and digest:
https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
Your CreateTemporaryFile method should be marked async and you should be awaiting those calls.
So, to your problem. You're calling fileStream.WriteAsync(buffer, 0, read) without awaiting the Task's completion. On the (at least) last write, the stream will be disposed before the write is complete, with predicable results.
Adopt async properly or don't use it at all. There's no half-way house.
发布评论