使用.NET CORE 实战minio文件服务器,部署、集成,可以直接使用哈
[*]这里使用的环境是 .net core 3.0以上版本 centos服务器一台
MiniO对象存储服务是一中开源的文件存储器,我这里是将minio放在docker下运行
[*]
第一步:首先需要在环境中安装docker容器 (这里大家可以百度一下安装docker容器,很简单) 这里还是给一个参考地址吧:https://www.runoob.com/docker/centos-docker-install.html
[*]
第二步:这里就可以直接安装minio了,这里的我是自定义安装,执行一下命令: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文件服务器了,(这里帮公司省了一笔钱呢,可能现在有的公司还在用腾讯云、阿里云啥的{:1_918:})
废话不多说,直接上代码
[*]将部署好的Minio服务,绑定到项目上,实现文件的上传,返回相应的地址了
首先在文件Startup上添加一个依赖: 这里需要一个依赖包:Minio.AspNetCore
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业务层 就是连接、压缩、文件策略等
/// <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.FileName).Replace(".", "");
//是否是图片,现在只能是图片上传 文件类型 或扩展名不一致则返回
if (contentTypDict.Values.FirstOrDefault(c => c == file.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.FileName);
await _client.PutObjectAsync(bucketName, newFileName, file.OpenReadStream(), file.Length,
file.ContentType);
fileModel.Url = $"{_settings.FileURL}{newFileName}";
//是否是图片,是图片进行压缩
if (contentTypDict.Values.Contains(file.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.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;
}
}
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对象存储服务上
可能有些配置没有给到,我的都是在配置文件中,比如一些存储桶名,文件对外访问域名等。。
[*]在控器层调用接口
/// <summary>
/// 上传图片
/// </summary>
/// <returns></returns>
public async Task<Result<FileModel>> AddImg(FormFileCollection file)
{
return await _minIOService.UploadImageAsync(file);
}
以上如果有不懂的可以评论我,谢谢支持!!
感谢分享 我用docker hub 上的 开了个容器,但控制中心帐号密码 minioadmin登不进去呢。是run的时候配还是 默认什么的,文档上也没写 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了 4个g的大文件如何弄?{:1_907:}
页:
[1]