亚马逊提供了大量的文档,但是我丢失了很多文档,所以这是我目前的上传/下载文件服务。上传按预期工作,但在下载时我必须将文件下载到物理路径,然后将下载提供给用户,我没有多少使用流的经验。这是连接到Amazon API的FileManagerService类。
using Amazon.S3;
using Amazon.S3.Model;
public class FileManagerService
{
public FileManagerService()
{
string serverPath = HttpContext.Current.Server.MapPath("~/");
string uploadPath = Path.Combine(serverPath, "FileUploads");
Directory.CreateDirectory(uploadPath);
UploadDirectory = uploadPath;
}
private string UploadDirectory { get; set; }
private docucloudEntities db = new docucloudEntities();
private IAmazonS3 S3Client = new AmazonS3Client();
private string S3Bucket = "bucketname";
public async Task<string> DownloadFile(string AmazonFileKey, string FileName)
{
var fileRequest = new GetObjectRequest
{
BucketName = S3Bucket,
Key = AmazonFileKey
};
var localRoute = Path.Combine(UploadDirectory, FileName);
using (var fileObject = await S3Client.GetObjectAsync(fileRequest))
{
if (fileObject.HttpStatusCode == HttpStatusCode.OK)
{
fileObject.WriteResponseStreamToFile(localRoute);
}
}
return localRoute;
}
}
此方法返回字符串,但它还没有完成try catch块,但它目前有效。这是我的控制器方法,将文件下载到客户端:
public class FileManagerController : Controller
{
private FileManagerService FileService = new FileManagerService();
public async Task<ActionResult> DownloadFileAmazon(long FileId)
{
if (db.Archivos.Any(i => i.ArchivoID == FileId))
{
var archivo = db.Archivos.Single(i => i.ArchivoID == FileId);
var rutaarchivo = await FileService.DownloadFile(archivo.Ruta, archivo.Nombre);
if (System.IO.File.Exists(rutaarchivo))
{
var fileBytes = System.IO.File.ReadAllBytes(rutaarchivo);
var response = new FileContentResult(fileBytes, "application/octet-stream");
response.FileDownloadName = archivo.Nombre;
System.IO.File.Delete(rutaarchivo);
return response;
}else
{
return HttpNotFound();
}
}else
{
return HttpNotFound();
}
}
}
所以在控制器上我读取文件字节并在删除文件后提供下载,但这可能导致性能降低,有一种实现直接下载的方法。
答案 0 :(得分:0)
据我所知,即使文档这样说,也没有理由处理GetObjectResponse
(GetObjectAsync
的返回类型)。 GetObjectResponse
未实施IDisposable
,但正在继承StreamResponse
。但是,据我所知it's only disposing the ResponseStream
。因此,您可以将GetObjectResponse
(fileObject.ResponseStream
)的流与标题(ContentType
)中的fileObject.Headers.ContentType
一起返回,然后您可以将其作为控制器中的文件返回:< / p>
[HttpGet]
[Route("blob/{filename}")]
public async Task<IActionResult> GetFile(string filename)
{
try
{
var file = await _fileStorageService.GetBlobAsync(filename);
return File(file.Stream, file.ContentType);
}
catch (Exception ex)
{
// Handle exceptions
}
}
FileResult
将在写入文件后处理该流,以便流最终得到处理。