OSS会为每个对象生成MD5,这样判断是否需要上传和下载就是判断MD5是否相等,比用数据库的表保存方便。
哭笑不得的是阿里云的OSS的MD5值居然非得加个引号(估计能多赚点流量费用)
还有阿里的OSS SDK或者说阿里的SDk的开发者有严重的拼代码的嫌疑(就是代码量相当大),所以自己划拉了一个类,把自己需要的方法封装了一下
public enum EBucket
{
App, Test, Publish, InfoIdCard, Common, Hotels
}
public static class OSSHelper
{
private const string AccessKeyId = "您的KeyId";
private const string AccessKeySecret = "您的KeySecret";
private const string EndPoint = "oss-cn-hangzhou.aliyuncs.com";
static HttpClient _HttpClient = new HttpClient();
static byte[] _Key = Encoding.UTF8.GetBytes(AccessKeySecret);
private readonly static Dictionary<EBucket, string> _DBucketName = new Dictionary<EBucket, string>()
{
{ EBucket.App,"ykmain" },
{ EBucket.Test,"ykdlltest" },
{ EBucket.Publish,"ykdll" },
{ EBucket.InfoIdCard,"infocards" },
{ EBucket.Common,"ykcommon" },
{ EBucket.Hotels,"ykhotel" },
};
public static async Task<bool> CopyDllAsync(string key)
{
try
{
var dt = DateTime.Now.ToUniversalTime();
var date = dt.ToString("r");
var sign = HashHelper.SignHMACSHA1(_Key, $"PUT\n\n\n{date}\nx-oss-copy-source:/ykdlltest/{key}\n/ykdll/{key}");
_HttpClient.DefaultRequestHeaders.Host = $"ykdll.{EndPoint}";
_HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("OSS", $"{AccessKeyId}:{sign}");
_HttpClient.DefaultRequestHeaders.Date = dt;
_HttpClient.DefaultRequestHeaders.Add("x-oss-copy-source", $"/ykdlltest/{key}");
//StreamContent streamContent = new StreamContent(new MemoryStream());
var r = await _HttpClient.PutAsync($"http://ykdll.{EndPoint}/{key}", null);// streamContent);
if (!r.IsSuccessStatusCode)
{
var str = await r.Content.ReadAsStringAsync();
LogHelper.Write(str);
}
return r.IsSuccessStatusCode;
}
finally
{
_HttpClient.DefaultRequestHeaders.Remove("x-oss-copy-source");//, $"/ykdlltest/{key}");
}
}
#region Base Operate
public static async Task<bool> SaveFileAsync(EBucket bucket, string filename, byte[] buffer)
{
var bucketName = _DBucketName[bucket];
var dt = DateTime.Now.ToUniversalTime();
var date = dt.ToString("r");
var sign = HashHelper.SignHMACSHA1(_Key, $"PUT\n\napplication/octet-stream\n{date}\n/{bucketName}/{filename}");
_HttpClient.DefaultRequestHeaders.Host = $"{bucketName}.{EndPoint}";
_HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("OSS", $"{AccessKeyId}:{sign}");
_HttpClient.DefaultRequestHeaders.Date = dt;
using var ms = new MemoryStream(buffer);
StreamContent streamContent = new StreamContent(ms);
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
try
{
var r = await _HttpClient.PutAsync($"http://{bucketName}.{EndPoint}/{filename}", streamContent);
if (!r.IsSuccessStatusCode)
LogHelper.Write(await r.Content.ReadAsStringAsync());
return r.IsSuccessStatusCode;
}
catch (Exception ex)
{
LogHelper.Write(ex);
return false;
}
}
public static async Task<bool> SavePublicReadFileAsync(EBucket bucket, string filename, byte[] buffer)
{
var bucketName = _DBucketName[bucket];
var dt = DateTime.Now.ToUniversalTime();
var date = dt.ToString("r");
var sign = HashHelper.SignHMACSHA1(_Key, $"PUT\n\napplication/octet-stream\n{date}\nx-oss-object-acl:public-read\n/{bucketName}/{filename}");
_HttpClient.DefaultRequestHeaders.Host = $"{bucketName}.{EndPoint}";
_HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("OSS", $"{AccessKeyId}:{sign}");
_HttpClient.DefaultRequestHeaders.Date = dt;
using var ms = new MemoryStream(buffer);
StreamContent streamContent = new StreamContent(ms);
streamContent.Headers.Add("x-oss-object-acl", "public-read");
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
try
{
var r = await _HttpClient.PutAsync($"http://{bucketName}.{EndPoint}/{filename}", streamContent);
if (!r.IsSuccessStatusCode)
LogHelper.Write(await r.Content.ReadAsStringAsync());
return r.IsSuccessStatusCode;
}
catch (Exception ex)
{
LogHelper.Write(ex);
return false;
}
}
public static async Task<FileMetas> GetFileMetasAsync(EBucket bucket, string directoryName = "", string delimiter = "")
{
var bucketName = _DBucketName[bucket];
string resource = "?list-type=2&max-keys=1000";
if (!string.IsNullOrEmpty(directoryName))
resource += $"&prefix={directoryName}/";
if (!string.IsNullOrEmpty(delimiter))
resource += $"&delimiter={delimiter}";
var dt = DateTime.Now.ToUniversalTime();
var date = dt.ToString("r");
string stringToSign = $"GET\n\n\n{date}\n/{bucketName}/";
string sign = HashHelper.SignHMACSHA1(_Key, stringToSign);
_HttpClient.DefaultRequestHeaders.Host = $"{bucketName}.oss-cn-hangzhou.aliyuncs.com";
_HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("OSS", $"{AccessKeyId}:{sign}");
_HttpClient.DefaultRequestHeaders.Date = dt;
try
{
var r = await _HttpClient.GetAsync($"http://{bucketName}.{EndPoint}{resource}");
var str = await r.Content.ReadAsStringAsync();
if (!r.IsSuccessStatusCode)
{
LogHelper.Write(str);
return default;
}
return str.XmlDeser<FileMetas>();
}
catch (Exception ex)
{
LogHelper.Write(ex);
return default;
}
}
public static async Task<byte[]> GetFileAsync(EBucket bucket, string filename)
{
var bucketName = _DBucketName[bucket];
var dt = DateTime.Now.ToUniversalTime();
var date = dt.ToString("r");
var sign = HashHelper.SignHMACSHA1(AccessKeySecret, $"GET\n\n\n{date}\n/{bucketName}/{filename}");
_HttpClient.DefaultRequestHeaders.Host = $"{bucketName}.{EndPoint}";
_HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("OSS", $"{AccessKeyId}:{sign}");
_HttpClient.DefaultRequestHeaders.Date = dt;
try
{
var r = await _HttpClient.GetAsync($"http://{bucketName}.{EndPoint}/{filename}");
if (!r.IsSuccessStatusCode)
{
LogHelper.Write(await r.Content.ReadAsStringAsync());
return default;
}
else
return await r.Content.ReadAsByteArrayAsync();
}
catch (Exception ex)
{
LogHelper.Write(ex);
return default;
}
}
public static async Task<bool> DeleteFileAsync(EBucket bucket, string filename)
{
var bucketName = _DBucketName[bucket];
var dt = DateTime.Now.ToUniversalTime();
var date = dt.ToString("r");
var sign = HashHelper.SignHMACSHA1(AccessKeySecret, $"DELETE\n\n\n{date}\n/{bucketName}/{filename}");
_HttpClient.DefaultRequestHeaders.Host = $"{bucketName}.{EndPoint}";
_HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("OSS", $"{AccessKeyId}:{sign}");
_HttpClient.DefaultRequestHeaders.Date = dt;
try
{
var r = await _HttpClient.DeleteAsync($"http://{bucketName}.{EndPoint}/{filename}");
if (!r.IsSuccessStatusCode)
{
var str = await r.Content.ReadAsStringAsync();
LogHelper.Write(str);
}
return r.IsSuccessStatusCode;
}
catch (Exception ex)
{
LogHelper.Write(ex);
return false;
}
}
public static async Task<bool> DeleteFilesAsync(EBucket bucket, List<string> filenames)
{
var bucketName = _DBucketName[bucket];
var dt = DateTime.Now.ToUniversalTime();
var date = dt.ToString("r");
var xmlstr = new DeleteFileNames() { Items = filenames.Select(ii => new DeleteFileNames.Item { Key = ii }).ToList() }.XmlSer();
var md5 = HashHelper.GetMD5Bytes(Encoding.UTF8.GetBytes(xmlstr));
var sign = HashHelper.SignHMACSHA1(AccessKeySecret, $"POST\n{Convert.ToBase64String(md5)}\ntext/xml\n{date}\n/{bucketName}/?delete");
_HttpClient.DefaultRequestHeaders.Host = $"{bucketName}.{EndPoint}";
_HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("OSS", $"{AccessKeyId}:{sign}");
_HttpClient.DefaultRequestHeaders.Date = dt;
StringContent content = new StringContent(xmlstr);
content.Headers.ContentType = new MediaTypeHeaderValue("text/xml");
content.Headers.ContentMD5 = md5;
try
{
var r = await _HttpClient.PostAsync($"http://{bucketName}.{EndPoint}/?delete", content);
if (!r.IsSuccessStatusCode)
LogHelper.Write(await r.Content.ReadAsStringAsync());
return r.IsSuccessStatusCode;
}
catch (Exception ex)
{
LogHelper.Write(ex);
return false;
}
}
}
#endregion
文字必须多点文字必须多点文字必须多点文字必须多点文字必须多点文字必须多点文字必须多点文字必须多点文字必须多点文字必须多点文字必须多点文字必须多点文字必须多点文字必须多点文字必须多点文字必须多点文字必须多点文字必须多点文字必须多点文字必须多点文字必须多点
分类:
WPF学习
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)