亚马逊提供了大量的文档,但是有很多文档我丢失了,所以这是我目前的上传/下载文件服务 . 上传按预期工作,但在下载时我必须将文件下载到物理路径,然后将下载提供给用户,我没有多少使用流的经验 . 这是连接到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();
}
}
}
所以在控制器上我读取文件字节并在删除文件后提供下载,但这可能导致性能降低,有一种实现直接下载的方法 .
1 回答
据我所知,即使文档这样说,也没有理由处理
GetObjectResponse
(返回类型GetObjectAsync
) .GetObjectResponse
未实现IDisposable
但继承StreamResponse
. 但是,据我所知,it's only disposing the ResponseStream . 因此,您可以将来自GetObjectResponse
(fileObject.ResponseStream
)的流与 Headers (fileObject.Headers.ContentType
)中的ContentType
一起返回,然后您可以将其作为控制器中的文件返回:FileResult
将在写入文件后处理流,以便流最终得到处理 .