一、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,選擇要上傳的文件上傳,測試效果
上傳后的文件: