在ASP.Net Core中,推荐的返回文件的方法是通过PhysicalFileProvider
获取访问权限,这提供了额外的安全性,包括确定目录及其子目录的所有路径。目前我的整个应用程序都是Async,我希望我的所有方法都能保持这样。
public static string BASE_PATH = Path.GetTempPath();
public static string lastSavedFilePath = @"C:\Users\MyUser\AppData\Local\Temp\MyPicture.png"
[HttpGet("{id}")]
public async Task<FileResult> GetFileById(int id)
{
//provides access to the physical file system, scoping all paths to a directory and its children
IFileProvider provider = new PhysicalFileProvider(BASE_PATH);
var fileInfo = provider.GetFileInfo(lastSavedFilePath);
var fileStream = fileInfo.CreateReadStream();
this._contentTypeProvider.TryGetContentType(lastSavedFilePath, out var mimeType);
return File(fileStream, mimeType, "ProfilePicture.png");
}
修改
事实证明通过PhysicalFileProvider
获取文件并不是我想要的异步,我真的希望将Stream读取为异步。
如何确保在调用文件操作时它会读取我的流Async?
答案 0 :(得分:5)
PhysicalFileProvider
完全能够读取异步文件。 GetFileInfo
返回有关文件的信息,这里没有什么应该做异步。它类似于new FileInfo("path")
。
CreateReadStream
获取目标文件的句柄,它类似于File.OpenRead()
。再一次 - 这里没有什么应该是异步的,而不是你是否使用PhysicalFileProvider
。
当你有文件流时 - 你可以像往常一样异步读取它(ReadAsync
等等),无论你如何获得它。实际上,PhysicalFileProvider.CreateReadStream
甚至打开带有正确标志(FileOptions.Asynchronous
)的文件,使该流非常适合异步访问(并且不适合非异步访问)。
在您的情况下,虽然您不需要自己阅读该文件流。你正确地用
返回它return File(fileStream, mimeType, "ProfilePicture.png");
这已经为您读取和写入该文件到http响应流异步。这是因为您返回的所有ActionResult
(包括FileStreamResult
}都有Task ExecuteAsync
方法来实际执行该结果。 Asp.net将为您执行await yourFileResult.ExecuteAsync()
,ExecuteAsync
将异步复制文件流到http响应。
简而言之 - 只需签名
public FileResult GetFileById(int id)
你会没事的。异步应该做什么 已经在此代码中异步完成。