ASP.NET Core(C#) 存储上传的文件接口及实现方法

本文主要介绍ASP.NET Core(C#)中,封装存储上传文件的接口,包括本地存储和web目录存储实现方法,包括虚拟路径转换物理路径方法,生成文件目录方法,同步和和异步保存文件流方法,以及相关的示例代码。

1、文件存储接口

using System.IO;
using System.Threading.Tasks;
namespace CJavaPy.Storage
{
    public interface IStorage
    {
        string SaveFile(Stream stream, string fileName);
        Task<string> SaveFileAsync(Stream stream, string fileName);
        string SaveFile(Stream stream, string directory, string fileName);
        Task<string> SaveFileAsync(Stream stream, string directory, string fileName);
        void AppendFile(Stream stream, string filePath);
        Task AppendFileAsync(Stream stream, string filePath);
        void Delete(string filePath);
        void DeleteDirectory(string path);
    }
}

2、本地存储实现接口方法

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace CJavaPy.Storage
{
    public class LocalStorage : IStorage
    {
        public string ToFilePath(string path)
        {
            return Path.Combine(path.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries));
        }
        //虚拟路径转成物理路径
        protected virtual string MapPath(string path)
        {
            return Path.Combine(Directory.GetCurrentDirectory(), ToFilePath(path.TrimStart('~')));
        }
        //生成文件目录
        protected virtual string GenerateDictionary(string fileName)
        {
            return Path.Combine("Files", fileName);
        }
        //追加文件内容
        public virtual void AppendFile(Stream stream, string filePath)
        {
            using (FileStream fileStream = new FileStream(MapPath(filePath), FileMode.Append))
            {
                stream.CopyTo(fileStream);
            }
        }
       //异步追加文件内容
        public virtual async Task AppendFileAsync(Stream stream, string filePath)
        {
            using (FileStream fileStream = new FileStream(MapPath(filePath), FileMode.Append))
            {
                await stream.CopyToAsync(fileStream);
            }
        }
       //删除文件
        public virtual void Delete(string filePath)
        {
            File.Delete(MapPath(filePath));
        }
          //指定文件名同步保存文件
        public virtual string SaveFile(Stream stream, string fileName)
        {
            return SaveFile(stream, GenerateDictionary(fileName), fileName);
        }
       //指定文件名异步保存文件
        public virtual Task<string> SaveFileAsync(Stream stream, string fileName)
        {
            return SaveFileAsync(stream, GenerateDictionary(fileName), fileName);
        }
       // 指定目录和文件名同步保存文件
        public virtual string SaveFile(Stream stream, string directory, string fileName)
        {
            string filePath = Path.Combine(MapPath(directory), fileName);
            using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
            {
                stream.CopyTo(fileStream);
            }
            return filePath;
        }
         //指定目录和文件名异步保存文件
        public virtual async Task<string> SaveFileAsync(Stream stream, string directory, string fileName)
        {
            string filePath = Path.Combine(MapPath(directory), fileName);
            using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
            {
               await stream.CopyToAsync(fileStream);
            }
            return filePath;
        }
        public virtual void DeleteDirectory(string path)
        {
            Directory.Delete(MapPath(path), true);
        }
    }
}

3、Web目录(wwwroot)存储实现接口方法

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;

namespace CJavaPy.Storage
{
    public class WebStorage : IStorage
    {
        const string WebRoot = "wwwroot";
        const string UploadFolder = "UpLoad";
        const string ImageFolder = "Images";
        const string FileFolder = "Files";
       //判断图片
        public bool IsImage(string extension)
        {
            extension = extension.ToLower();
            if (extension == ".gif" || extension == ".jpg" || extension == ".png" || extension == ".jpeg" || extension == ".bmp")
            {
                return true;
            }
            else return false;
        }
        //路径转换
        public string ToFilePath(string path)
        {
            return Path.Combine(path.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries));
        }
       //虚拟路径转成物理路径
        protected virtual string MapPath(string path)
        {
            return Path.Combine(Directory.GetCurrentDirectory(), WebRoot, ToFilePath(path.TrimStart('~')));
        }
        //生成上传目录路径
        protected virtual string GenerateDictionary(string fileName)
        {
            string folder = IsImage(Path.GetExtension(fileName)) ? ImageFolder : FileFolder;
            return Path.Combine(new string[] { UploadFolder, folder, DateTime.Now.ToString("yyyyMM") });
        }
        //追加文件内容
        public virtual void AppendFile(Stream stream, string filePath)
        {
            using (FileStream fileStream = new FileStream(MapPath(filePath), FileMode.Append))
            {
                stream.CopyTo(fileStream);
            }
        }
        //异步追加文件内容
        public virtual async Task AppendFileAsync(Stream stream, string filePath)
        {
            using (FileStream fileStream = new FileStream(MapPath(filePath), FileMode.Append))
            {
                await stream.CopyToAsync(fileStream);
            }
        }
        //删除文件
        public virtual void Delete(string filePath)
        {
            FileInfo file = new FileInfo(MapPath(filePath));
            if (file.Exists)
            {
                file.Delete();
            }
        }
       //指定文件名保存文件
        public virtual string SaveFile(Stream stream, string fileName)
        {
            return SaveFile(stream, GenerateDictionary(fileName), fileName);
        }
        //异步保存文件
        public virtual Task<string> SaveFileAsync(Stream stream, string fileName)
        {
            return SaveFileAsync(stream, GenerateDictionary(fileName), fileName);
        }
       //指定目录和文件名保存文件
        public virtual string SaveFile(Stream stream, string directory, string fileName)
        {
            string filePath = Path.Combine(MapPath(directory), fileName);
            DirectoryInfo dir = new DirectoryInfo(Path.GetDirectoryName(filePath));
            if (!dir.Exists)
            {
                dir.Create();
            }
            using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
            {
                stream.CopyTo(fileStream);
            }
            string webPath = string.Join("/", directory.Split(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries));
            return $"~/{webPath}/{fileName}";
        }
         //指定目录和文件名异步保存文件
        public virtual async Task<string> SaveFileAsync(Stream stream, string directory, string fileName)
        {
            string filePath = Path.Combine(MapPath(directory), fileName);
            DirectoryInfo dir = new DirectoryInfo(Path.GetDirectoryName(filePath));
            if (!dir.Exists)
            {
                dir.Create();
            }
            using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
            {
                await stream.CopyToAsync(fileStream);
            }
            string webPath = string.Join("/", directory.Split(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries));
            return $"~/{webPath}/{fileName}";
        }
        public virtual void DeleteDirectory(string path)
        {
            Directory.Delete(MapPath(path), true);
        }
    }
}

推荐阅读
cjavapy编程之路首页