怎么实现动态设置静态文件存储目录?

前言

文章名字有点绕口,举例说明一下:

多用户使用同一个网站上传文件,但是因为一些原因,文件需要存储到服务器的不同目录下。

比如用户 A 对应 c:\abc,用户 B 对应 d:\xyz\123

并且,文件需要以静态文件方式提供访问。

由于每个用户的静态文件存储目录不同,这就需要根据用户当前请求动态确定存储目录。

怎么实现?

思路

默认情况下,静态文件存储在项目的 Web 根目录中。默认目录为 {content root}/wwwroot

如果要使用其他目录,可以按如下方式配置静态文件中间件:

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(@"c:\abc")
});

查看 FileProvider 属性,它是 IFileProvider 接口的实例:

public interface IFileProvider
{
    IFileInfo GetFileInfo(string subpath);

    ...
}

其中,subpath 是相对于 Web 根目录的标识文件的相对路径:

https://<hostname>/StaticFiles/images/red-rose.jpg

//subpath
/StaticFiles/images/red-rose.jpg

//静态文件路径
c:\abc\StaticFiles\images\red-rose.jpg

如果 subpath 有规律(比如以用户 Id 为第一级子目录),我们可以实现自定义 IFileProvider,通过 subpath 反向映射出静态文件路径。

例如:

subpath静态文件路径
/userAId/1.jpgc:\abc\userAId\1.jpg
/userBId/1.jpgd:\xyz\123\userBId\1.jpg

实现

创建 MyIOFileProvider,代码如下:

public class MyIOFileProvider : IFileProvider
{
    public IDirectoryContents GetDirectoryContents(string subpath)
    {
        return GetPhysicalFileProvider(subpath).GetDirectoryContents(subpath);
    }

    public IFileInfo GetFileInfo(string subpath)
    {
        return GetPhysicalFileProvider(subpath).GetFileInfo(subpath);
    }

    public IChangeToken Watch(string filter)
    {
        return null;
    }
}

然后根据 subpath 获取对应的 PhysicalFileProvider 进行处理:

private PhysicalFileProvider GetPhysicalFileProvider(string subpath)
{
    //实际可从数据库获取
    if (subpath.StartsWith("/1/"))
    {
        return new PhysicalFileProvider(@"c:\abc");
    }
    if (subpath.StartsWith("/2/"))
    {
        return new PhysicalFileProvider(@"d:\xyz\123");
    }

    ...
}

使用

按如下方式配置静态文件中间件:

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new MyIOFileProvider()
});

运行效果如图:

4e10401dbf693a99cc4213f4d75e1e1f.gif

结论

今天,我们通过自定义 IFileProvider,实现了动态设置静态文件存储目录。

想了解更多内容,请关注我的个人公众号”My IO“

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值