minIO系列文章04---windows下安装及在.netcore使用
一、minio下载与启动
下载后会有一个minio.exe文件,放到指定的目录
在该目录下运行:minio.exe server D:\minio\file 出现如下的提示代码启动动成功:
浏览器中输入:http://127.0.0.1:9000/ 进入minio登录页面 用户名密码:minioadmin minioadmin
可以看到我在桶omsfile中上传了两个文件
二、.netcore中集成
1、引入Nuget包 Minio.AspNetCore
2、配置json文件
"Minio": { "Endpoint": "127.0.0.1:9000", "Region": "127.0.0.1", "AccessKey": "minioadmin", "SecretKey": "minioadmin", "BucketName": "omsfile", "FileURL": "http://127.0.0.1:9000/file" }
3、添加服务
services.AddMinio(options => { options.Endpoint = Configuration["Minio:Endpoint"]; // 这里是在配置文件接口访问域名 options.Region = Configuration["Minio:Region"]; // 地址 options.AccessKey = Configuration["Minio:AccessKey"]; // 用户名 options.SecretKey = Configuration["Minio:SecretKey"]; // 密码 });
4、服务接口 IMinIOService
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); }
5、服务接口实现 MinIOService
/// <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; Zhengwei.Minio.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 = $"{newFileName}"; var savepath = $"{path}{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 //上传压缩图 using (var sw = new FileStream(savepath, FileMode.Open)) { await _client.PutObjectAsync(bucketName, bImageName, sw, sw.Length, "image/jpeg"); fileModel.Url = $"{_settings.FileURL}{bImageName}"; } if (Directory.Exists(Path.GetDirectoryName(path))) Directory.Delete(Path.GetDirectoryName(path), true); } res.IsSuccess = 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.IsSuccess = 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; } }
6、注入服务
services.AddSingleton<IMinIOService, MinIOService>();
7、其它需要的类
public class Result<T> { public Result(bool isSuccess,string msg) { this.IsSuccess = isSuccess; this.Msg = msg; } public bool IsSuccess { get; set; } public string Code { get; set; } public string Msg { get; set; } /// <summary> /// 返回数据列表 /// </summary> public Object Data { set; get; } }
public class FileModel { public string Url { get; set; } }
8、上传文件的api
[ApiController] [Route("[controller]")] public class FileManagerController : Controller { public IMinIOService _minIOService { get; set; } public FileManagerController(IMinIOService minIOService) { this._minIOService = minIOService; } [Route("UploadImg")] /// <summary> /// 上传图片 /// </summary> /// <returns></returns> [HttpPost] public async Task<Result<FileModel>> UploadImg(FormFileCollection file) { return await _minIOService.UploadImageAsync(file); } }
9、启动swagger,选择要上传的文件上传,测试效果
上传后的文件: