吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4644|回复: 4
收起左侧

[其他转载] 使用.NET CORE 实战minio文件服务器,部署、集成,可以直接使用哈

[复制链接]
微笑小生 发表于 2021-12-24 10:09
  • 这里使用的环境是 .net core 3.0以上版本   centos服务器一台

MiniO对象存储服务是一中开源的文件存储器,我这里是将minio放在docker下运行


  • 第一步:首先需要在环境中安装docker容器 (这里大家可以百度一下安装docker容器,很简单) 这里还是给一个参考地址吧:https://www.runoob.com/docker/centos-docker-install.html

  • 第二步:这里就可以直接安装minio了,这里的我是自定义安装,执行一下命令:
    [C#] 纯文本查看 复制代码
    docker run -d --restart always \  -p 9000:9000 \
      -p 9001:9001 \
      --name minio \
      -v /mnt/data:/data \
      -e "MINIO_ROOT_USER=admin" \
      -e "MINIO_ROOT_PASSWORD=admin123456" \
      minio/minio server /data --console-address ":9001"



说明一下: 9000和9001是端口号,如果被占用,可以使用其他的端口号, - v就是路径了,这里可以创建一个,或者使用其他的路径就好了  下面就是用户名和密码,命令使用成功后,这里开源的minio会帮我们生成一个管理的客户端,使用外网IP加9001的端口访问
参数地址:http://docs.minio.org.cn/docs/master/minio-monitoring-guide
效果为:
   


以上部署好了,接下来就是在项目中集成minio文件服务器了,(这里帮公司省了一笔钱呢,可能现在有的公司还在用腾讯云、阿里云啥的

废话不多说,直接上代码

  • 将部署好的Minio服务,绑定到项目上,实现文件的上传,返回相应的地址了

首先在文件Startup上添加一个依赖: 这里需要一个依赖包:Minio.AspNetCore
[C#] 纯文本查看 复制代码
services.AddMinio(options =>
            {
                options.Endpoint = _config.GetSection("Startup")["Minio:Endpoint"];  // 这里是在配置文件接口访问域名
                options.Region = _config.GetSection("Startup")["Minio:Region"];  // 地址
                options.AccessKey = _config.GetSection("Startup")["Minio:AccessKey"];  // 用户名
                options.SecretKey = _config.GetSection("Startup")["Minio:SecretKey"];   // 密码
                
            });

services.AddSingleton<IMinIOService, MinIOService>();


此时有人会问:MinIOService 这个文件是干嘛的,这里是帖主封装的一个Minio业务层 就是连接、压缩、文件策略等

[C#] 纯文本查看 复制代码
 /// <summary>
    /// 上传文件相关
    /// </summary>
    public class MinIOService : IMinIOService
    {
        public AppSetting _settings { get; }
        public IHostingEnvironment _hostingEnvironment { get; set; }
        public MinioClient _client { get; set; }
        public MinioOptions _minioOptions { get; set; }
        public MinIOService(IOptions<AppSetting> setting, IHostingEnvironment hostingEnvironment, MinioClient client, IOptions<MinioOptions> minioOptions)
        {
            _settings = setting.Value;
            _hostingEnvironment = hostingEnvironment;
            _client = client;
            _minioOptions = minioOptions.Value;
        }
        //获取图片的返回类型
        public static Dictionary<string, string> contentTypDict = new Dictionary<string, string> {
                {"bmp","image/bmp" },
                {"jpg","image/jpeg"},
                {"jpeg","image/jpeg"},
                {"jpe","image/jpeg"},
                {"png","image/png"},
                {"gif","image/gif"},
                {"ico","image/x-ico"},
                {"tif","image/tiff"},
                {"tiff","image/tiff"},
                {"fax","image/fax"},
                {"wbmp","image//vnd.wap.wbmp"},
                {"rp","image/vnd.rn-realpix"} };


        /// <summary>
        /// 上传图片
        /// </summary>
        /// <param name="file">文件</param>
        /// <returns></returns>

        public async Task<Result<FileModel>> UploadImageAsync(FormFileCollection file)
        {
            Result<FileModel> res = new Result<FileModel>(false, "上传失败");

            //获得文件扩展名
            string fileNameEx = System.IO.Path.GetExtension(file[0].FileName).Replace(".", "");

            //是否是图片,现在只能是图片上传 文件类型 或扩展名不一致则返回
            if (contentTypDict.Values.FirstOrDefault(c => c == file[0].ContentType.ToLower()) == null || contentTypDict.Keys.FirstOrDefault(c => c == fileNameEx) == null)
            {
                res.Msg = "图片格式不正确";
                return res;
            }
            else
                return await UploadAsync(file);
        }

        

        /// <summary>
        /// 上传
        /// </summary>
        /// <param name="file">文件</param>
        /// <returns></returns>

        public async Task<Result<FileModel>> UploadAsync(FormFileCollection file)
        {
            Result<FileModel> res = new Result<FileModel>(false, "上传失败");
            try
            {

                //存储桶名
                string bucketName = _settings.BucketName;

                FileModel fileModel = new FileModel();
                await CreateBucket(bucketName);
                var newFileName = CreateNewFileName(bucketName, file[0].FileName);
                await _client.PutObjectAsync(bucketName, newFileName, file[0].OpenReadStream(), file[0].Length,
                    file[0].ContentType);
                fileModel.Url = $"{_settings.FileURL}{newFileName}";

                //是否是图片,是图片进行压缩
                if (contentTypDict.Values.Contains(file[0].ContentType.ToLower()))
                {
                    string path = $"{_hostingEnvironment.ContentRootPath}/wwwroot/imgTemp/";
                    if (!Directory.Exists(Path.GetDirectoryName(path)))
                        Directory.CreateDirectory(Path.GetDirectoryName(path));

                    var bImageName = $"m_{newFileName}";
                    var savepath = $"{path}m_{newFileName}";//保存绝对路径
                    #region 保存原图到本地
                    using (FileStream fs = System.IO.File.Create(path + newFileName))
                    {
                        file[0].CopyTo(fs);
                        fs.Flush();
                    }
                    #endregion

                    #region 保存缩略图到本地
                    var bUrlRes = TencentCloudImageHelper.GetThumbnailImage(240, newFileName, path);
                    #endregion

                    //上传压缩图
                    if (bUrlRes.Res)
                    {
                        using (var sw = new FileStream(savepath, FileMode.Open))
                        {
                            await _client.PutObjectAsync(bucketName, bImageName, sw, sw.Length,
                 "image/jpeg");
                            fileModel.BUrl = $"{_settings.FileURL}{bImageName}";
                        }

                        if (Directory.Exists(Path.GetDirectoryName(path)))
                            Directory.Delete(Path.GetDirectoryName(path), true);
                    }
                }
                res.Res = true;
                res.Msg = "上传成功";
                res.Data = fileModel;
                return res;
            }
            catch (Exception e)
            {

                return res;
            }
        }

        public async Task<Result<FileModel>> UploadPdf(Stream file)
        {
            Result<FileModel> res = new Result<FileModel>(false, "上传失败");
            try
            {
                
                //存储桶名
                string bucketName = _settings.BucketName;

                FileModel fileModel = new FileModel();
                await CreateBucket(bucketName);
                var newFileName = CreateNewFileName(bucketName, "授权书.pdf");
                await _client.PutObjectAsync(bucketName, newFileName, file, file.Length,
                    "application/pdf");
                fileModel.Url = $"{_settings.FileURL}{newFileName}";

                res.Res = true;
                res.Msg = "上传成功";
                res.Data = fileModel;
                return res;
            }
            catch (Exception e)
            {

                return res;
            }
        }

        private async Task CreateBucket(string bucketName)
        {
            var found = await _client.BucketExistsAsync(bucketName);
            if (!found)
            {
                await _client.MakeBucketAsync(bucketName);
                //设置只读策略
                var pObj = new
                {
                    Version = "2012-10-17",
                    Statement = new[]
                    {
                        new
                        {
                            Effect = "Allow",
                            Principal = new
                            {
                                AWS = new [] {"*"}
                            },
                            Action = new [] {"s3:GetBucketLocation", "s3:ListBucket"},
                            Resource = new []
                            {
                                $"arn:aws:s3:::{bucketName}"
                            }
                        },
                        new
                        {
                            Effect = "Allow",
                            Principal = new
                            {
                                AWS = new [] {"*"}
                            },
                            Action = new [] {"s3:GetObject"},
                            Resource = new []
                            {
                                $"arn:aws:s3:::{bucketName}/*"
                            }
                        }
                    }
                };
                var po = JsonSerializer.Serialize(pObj);
                await _client.SetPolicyAsync(bucketName, po);
            }
        }

        private string CreateNewFileName(string bucketName, string oldFileName)
        {
            var dt =Guid.NewGuid().ToString().Replace("-", "").Substring(10)+ DateTimeOffset.Now.ToUnixTimeSeconds();
            var extensions = Path.GetExtension(oldFileName);
            var newFileName = $"{bucketName}-{dt}{extensions}";
            return newFileName;
        }
    }



[C#] 纯文本查看 复制代码
public interface IMinIOService
    {
        /// <summary>
        /// 上传
        /// </summary>
        /// <param name="file">文件</param>
        /// <returns></returns>
        Task<Result<FileModel>> UploadAsync(FormFileCollection file);

        /// <summary>
        /// 上传图片
        /// </summary>
        /// <param name="file">文件</param>
        /// <returns></returns>

        Task<Result<FileModel>> UploadImageAsync(FormFileCollection file);

        /// <summary>
        /// 上传pdf
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        Task<Result<FileModel>> UploadPdf(Stream file);
    }



此时接口已经写完了,下面就是在控制器层写一个简单的调用接口吧,然后看看是否上传到你的MiniO对象存储服务上

可能有些配置没有给到,我的都是在配置文件中,比如一些存储桶名,文件对外访问域名等。。

  • 在控器层调用接口

[C#] 纯文本查看 复制代码
/// <summary>
        /// 上传图片
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<Result<FileModel>> AddImg(FormFileCollection file)
        {
            return await _minIOService.UploadImageAsync(file);
        }


以上如果有不懂的可以评论我,谢谢支持!!



发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

zxxiaopi 发表于 2021-12-24 13:23
感谢分享
yunruifuzhu 发表于 2022-1-25 13:30
我用docker hub 上的 开了个容器,但控制中心帐号密码 minioadmin登不进去呢。是run的时候配还是 默认什么的,文档上也没写
 楼主| 微笑小生 发表于 2022-1-25 16:52
yunruifuzhu 发表于 2022-1-25 13:30
我用docker hub 上的 开了个容器,但控制中心帐号密码 minioadmin登不进去呢。是run的时候配还是 默认什么 ...

如果安装安装成功了。MINIO_ROOT_USER和MINIO_ROOT_PASSWORD 就是账户和密码,-v配置的就是日志目录,看看啥情况。我分享一下我的安装 docker run -d --restart always \
  -p 7000:7000 \
  -p 7001:7001 \
  --name minio \
  -v /mnt/data:/data \
  -e "MINIO_ROOT_USER=admin" \
  -e "MINIO_ROOT_PASSWORD=admin123456" \
  minio/minio server /data --console-address ":7001"

我这个是没有问题的,端口改成了7000了
我们该成熟 发表于 2022-5-18 09:42
4个g的大文件如何弄?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 06:30

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表