.net 5 上传文件到阿里云的OSS 文件的上传、下载 和文件的管理
1.先购买阿里云的oss服务器
2.添加子用户 会生成 AccessKeyId 和 AccessKeySecret 记录下来
3.给当前子用户添加管理阿里云oss 的权限
//所需要用到的类
public class FileBaseRequest { /// <summary> /// 文件名称 /// </summary> public string Name { get; set; } /// <summary> /// 文件大小 /// </summary> public long? Size { get; set; } /// <summary> /// 文件宽度 /// </summary> public int? Width { get; set; } /// <summary> /// 文件高度 /// </summary> public int? Height { get; set; } /// <summary> /// 文件类型 /// </summary> public string Type { get; set; } /// <summary> /// 文件唯一的Guid /// </summary> public string Guid { get; set; } /// <summary> /// 图片形状 /// </summary> public int ShapeTypeId { get; set; } /// <summary> /// url 地址 /// </summary> public string FilebaseUrl { get; set; } /// <summary> /// hash /// </summary> public string Hash { get; set; } }
public class DownFileInfo { public string Name { get; set; } public string Url { get; set; } }
public class ReturnBox { public int Code { get; set; } = 200; public object Data { get; set; } public string Message { get; set; } = "Success"; }
//连接的Helper 在使用前 在包管理工具中安装阿里云的包 Aliyun.OSS.Core, Version=2.13.0.0 按着自己的EF 或者 Core 都行
public class OSSHelper { #region Fields /// <summary> /// 正常的图片地址示例 /// </summary> //https://{仓名称}.oss-cn-hangzhou.aliyuncs.com/{文件目录}/filebase_dev/oringinal/123456789.png private static OssClient _ossClient; private static AutoResetEvent _event; //账号Id private const string AccessKeyId = "{你生成的key}"; //账号key private const string AccessKeySecret = "{你生成key的密钥}"; //oss所在的服务区域 private const string Endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; //生成的图片的路径地址 private const string Branch = @"{文件目录}/filebase_dev/"; // 填写Bucket名称。 private const string BucketName = "{仓名称}"; // 填写Object完整路径。Object完整路径中不能包含Bucket名称。 private const string objectName = "/{文件目录}/filebase_dev/"; // 填写字符串。 private const string objectContent = ""; /// <summary> /// 压缩大小 最小默认为 350 /// </summary> private const string ThumbSize = "350"; /// <summary> /// 其次是750 /// </summary> private const string DefaultSize = "750"; #endregion #region Utilities private OSSHelper() { _event = new AutoResetEvent(false); _ossClient = new OssClient(Endpoint, AccessKeyId, AccessKeySecret); } public static OSSHelper _() { return new OSSHelper(); } #endregion #region Method /// <summary> /// 非异步的方式 通过文件流单条上传到OSS /// </summary> /// <returns></returns> public async Task<FileBaseRequest> HttpUpload(IFormFile file) { //获取文件名称 string name = file.FileName; //获取文件类型 string type = file.ContentType; //通过随机生成的guid去当成图片的key string guid = Guid.NewGuid().ToString(); string filebaseUrl = string.Empty; //计算hash验证图片是否重复上传 string hash = ""; long? size = 0; int? width = 0; int? height = 0; int? shapeTypeId = 0; var strArr = type.Split('/'); using (var memoryStream = new MemoryStream()) { await file.CopyToAsync(memoryStream); size = file.Length; hash = ComputeMd5Hash(memoryStream); //默认图片目前没有其他类型的文件 不过换汤不换药 if (strArr[0].ToString() == "image") { using (Bitmap pic = new Bitmap(memoryStream)) { width = pic.Size.Width; height = pic.Size.Height; if (width > height) shapeTypeId = (int)ShapeType.Sideways; if (width < height) shapeTypeId = (int)ShapeType.vertical; if (width == height) shapeTypeId = (int)ShapeType.Square; } } else { } // //if (strArr[0].ToString() == "video") //{ //} byte[] oringinalBuffer, thumbBuffer, defaultBuffer; oringinalBuffer = memoryStream.ToArray(); thumbBuffer = GetThumbnail(oringinalBuffer, int.Parse(ThumbSize)); defaultBuffer = GetThumbnail(oringinalBuffer, int.Parse(DefaultSize)); using (MemoryStream requestContent = new MemoryStream(oringinalBuffer)) { filebaseUrl = $"{Branch}oringinal/{guid}.jpg"; _ossClient.PutObject(BucketName, filebaseUrl, requestContent); } using (MemoryStream requestContent = new MemoryStream(thumbBuffer)) { _ossClient.PutObject(BucketName, $"{Branch}thumb/{guid}.jpg", requestContent); } using (MemoryStream requestContent = new MemoryStream(defaultBuffer)) { _ossClient.PutObject(BucketName, $"{Branch}default/{guid}.jpg", requestContent); } } return new FileBaseRequest { FilebaseUrl = $" https://zww1.oss-cn-shenzhen.aliyuncs.com/{filebaseUrl}", Guid = guid, Hash = hash, Height = height, Name = name, ShapeTypeId = (int)shapeTypeId, Size = size, Type = type, Width = width, }; } /// <summary> /// 压缩图片 /// </summary> /// <param name="buffer"></param> /// <param name="targetSize">目标大小</param> /// <param name="orientation">旋转方向</param> /// <returns></returns> private Byte[] GetThumbnail(byte[] buffer, int targetSize, int orientation = 0) { using (var memoryStream = new MemoryStream(buffer)) { if (targetSize == 0) { return buffer; } using (Image image = new Bitmap(memoryStream)) { if (image.Width < targetSize) { return buffer; } //方向旋转 Rotation(image, image.Width, image.Height, 0); //计算比例 var data = CalculateDimensions(image.Size, targetSize); //开始压缩 System.Drawing.Image thumbImage = image.GetThumbnailImage(data.Width, data.Height, new Image.GetThumbnailImageAbort(ThumbnailCallback), System.IntPtr.Zero); using MemoryStream backStream = new MemoryStream(); thumbImage.Save(backStream, ImageFormat.Jpeg); //关闭缩略图对象 thumbImage.Dispose(); return backStream.GetBuffer(); } } } private bool ThumbnailCallback() { return false; } /// <summary> /// 方向选择 /// </summary> /// <param name="image"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="orientation"></param> private void Rotation(Image image, int width, int height, int orientation) { int ow = width; switch (orientation) { case 2: image.RotateFlip(RotateFlipType.RotateNoneFlipX); break; case 3: image.RotateFlip(RotateFlipType.Rotate180FlipNone); break; case 4: image.RotateFlip(RotateFlipType.RotateNoneFlipY); break; case 5: image.RotateFlip(RotateFlipType.Rotate90FlipX); break; case 6: image.RotateFlip(RotateFlipType.Rotate90FlipNone); width = height; height = ow; break; case 7: image.RotateFlip(RotateFlipType.Rotate270FlipX); break; case 8: image.RotateFlip(RotateFlipType.Rotate270FlipNone); width = height; height = ow; break; default: break; } } /// <summary> /// 等比例计算尺寸 /// </summary> /// <param name="oldSize"></param> /// <param name="targetSize"></param> /// <param name="autoResize"></param> /// <returns></returns> private Size CalculateDimensions(Size oldSize, int targetSize, bool autoResize = false) { Size newSize = new Size(); if (autoResize && oldSize.Height > oldSize.Width) { newSize.Width = (int)(oldSize.Width * ((float)targetSize / (float)oldSize.Height)); newSize.Height = targetSize; } else { newSize.Width = targetSize; newSize.Height = (int)(oldSize.Height * ((float)targetSize / (float)oldSize.Width)); } return newSize; } /// <summary> /// MD5加密 /// </summary> /// <param name="stream"></param> /// <returns></returns> private string ComputeMd5Hash(MemoryStream stream) { string hash = ""; using (MD5 md5 = MD5.Create()) { stream.Position = 0; foreach (var item in md5.ComputeHash(stream)) { hash += item.ToString("x2"); } } return hash; } /// <summary> /// 获取图片的宽高 /// </summary> /// <param name="file"></param> /// <returns></returns> public async Task<Tuple<int, int>> GetImagesInfo(IFormFile file) { int width = 0; int height = 0; using (var memoryStream = new MemoryStream()) { await file.CopyToAsync(memoryStream); using (Bitmap pic = new Bitmap(memoryStream)) { width = pic.Size.Width; height = pic.Size.Height; } } return new Tuple<int, int>(width, height); } /// <summary> /// 通过文件列表的Url地址下载文件 /// </summary> /// <param name="url">下载文件地址</param> /// <returns></returns> public async Task<Stream> HttpDownloadList(List<DownFileInfo> downFileInfos) { byte[] buffer; foreach (var item in downFileInfos) { RestClient restClient = new RestClient(); var request = new RestRequest(item.Url); var byteFile = restClient.DownloadData(request); } return null; } /// <summary> /// 单条下载 /// </summary> /// <returns></returns> public async Task<byte[]> HttpDownload(string url) { try { RestClient restClient = new RestClient(); var request = new RestRequest(url); var byteFile = restClient.DownloadData(request); return byteFile; } catch (Exception ex) { throw new AggregateException(ex.Message); } } /// <summary> /// 单条下载文件并转流 /// </summary> /// <param name="fileName">文件路径</param> /// <param name="isDelete">是否删除临时文件</param> /// <returns></returns> public Stream FileToStream(string fileName, bool isDelete = false, string url = null) { using (var client = new WebClient()) { string tempFile = Path.GetTempFileName(); client.DownloadFile(url, tempFile);//下载临时文件 //Console.WriteLine("Using " + tempFile); //打开文件 FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); // 读取文件的 byte[] byte[] bytes = new byte[fileStream.Length]; fileStream.Read(bytes, 0, bytes.Length); fileStream.Close(); // 把 byte[] 转换成 Stream Stream stream = new MemoryStream(bytes); if (isDelete) { File.Delete(fileName);//删除临时文件 } return stream; } } #endregion }
一切准备就绪后 使用 postman 测试
成功后返回当前图片的信息,在oss 中 生成不同类型的图片 选中图片能看到图片对应的 url
在本项目上传中使用的是简单上传
针对更多的上传方式 参考官方文档 https://www.alibabacloud.com/help/zh/doc-detail/91093.htm?spm=a2c63.p38356.b99.680.5fab7207rHS5QX
好了目前到这里就结束了 可自行扩展 仅供参考