之前玩了下百度bcs,觉得还不错,看了下云存储貌似没.net sdk 但是既然有api就好办嘛,自己动手写个文件上传试试
它的参数用了hmac签名,.net有自带的库,下面是签名方法,这个找了很久...参考着修改了下.还有个疑问,不知道百度是怎么验证签名内容的,因为我们只传入了sign,而hmac据说是不能解密的,只能用密钥来验证
/// <summary> /// 对数据进行Hmac签名 /// </summary> /// <param name="valueStr">要签名的数据</param> /// <param name="keyStr">密钥</param> /// <returns></returns> private string Hamc(string valueStr, string keyStr) { HMAC hmac = HMACSHA1.Create(); //源数据 var data = System.Text.Encoding.UTF8.GetBytes(valueStr); //密钥 var key = System.Text.Encoding.UTF8.GetBytes(keyStr); //设置密钥 hmac.Key = key; //计算哈希值 var hash = hmac.ComputeHash(data); //对数据进行签名 var signedData = hash.Concat(data).ToArray(); var receivedHash = signedData.Take(hmac.HashSize >> 3).ToArray(); String str = HttpUtility.UrlEncode(Convert.ToBase64String(receivedHash)); return str; }
然后就是上传文件到服务器了,可以看着进行修改下,下面的方法检索了流的sha1,如果服务器存在则直接返回地址.这里流的读取有一个注意的地方,不能一次读取流的全部,因为某些流不支持查找操作,所以先设了个40kb的缓存
/// <summary> /// 上传文件到百度空间,并写入文件数据库 /// </summary> /// <param name="input">输入流 该流必须能够读取</param> /// <param name="fileName">上传的文件名</param> /// <param name="bucket"></param> /// <returns></returns> public string UploadToBaidu(Stream input, string fileName, string bucket = "kecq-com") { if (String.IsNullOrEmpty(fileName)) { throw new Exception("savePath参数不能为空"); } fileName = fileName.TrimStart('/'); string savePath = "/" + DateTime.Now.Year + "/" + DateTime.Now.Month + "/" + DateTime.Now.Day + "/" + Guid.NewGuid().ToString("N") + Path.GetExtension(fileName); string fileUrl = "http://bcs.duapp.com/" + bucket + savePath; string Content = "MBO" + "\n" + "Method=PUT" + "\n" + "Bucket=kecq-com" + "\n" + "Object=" + savePath + "\n"; string sign = Hamc(Content, "xxxxxxxxxxxxx"); string url = "http://bcs.duapp.com/" + bucket + savePath + "?sign=MBO:D200252c02041aac02015b01656582bf:" + sign; HttpWebResponse res = null; string returnString = ""; try { List<byte> data = new List<byte>(); byte[] buffer = new byte[40960]; int read = input.Read(buffer, 0, buffer.Length); while (read > 0) { for (int i = 0; i < read; i++) { data.Add(buffer[i]); } read = input.Read(buffer, 0, buffer.Length); } input.Close(); //获取流的sha1码 System.Security.Cryptography.HashAlgorithm algorithm = System.Security.Cryptography.SHA1.Create(); String sha1 = BitConverter.ToString(algorithm.ComputeHash(data.ToArray())).Replace("-", ""); string writeDbUrl = "http://my.fyj.me/service/upload.action?method=POST&userID=xxxxxxxxx&flag=MU&ak=afbf3d192908477d9e24b3e351bc4ebe&sign=0PjZ80oM9HRgyJYGQtmawv2eiwI%3d"; writeDbUrl += "&action=saveFileDb&fileSha1=" + sha1 + "&fileName=" + fileName + "&fileSize=" + data.Count + "&fileUrl=" + HttpUtility.UrlEncode(fileUrl); string result = FYJ.Common.HttpHelper.DoGet(writeDbUrl); FYJ.Common.JsonHelper json = new FYJ.Common.JsonHelper(result); if (json.GetValue("code") != "1") { throw new Exception(json.GetValue("message")); } else { returnString = result; } if (json.GetValue("isFileExist") == "0") { HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.Method = "PUT"; req.ContentType = "application/x-www-form-urlencoded"; req.ContentLength = data.Count; Stream newStream = req.GetRequestStream(); newStream.Write(data.ToArray(), 0, data.Count); newStream.Close(); req.GetRequestStream(); res = (HttpWebResponse)req.GetResponse(); Stream ReceiveStream = res.GetResponseStream(); Encoding encode = System.Text.Encoding.UTF8; StreamReader sr = new StreamReader(ReceiveStream, encode); // strResult = sr.ReadToEnd(); sr.Close(); ReceiveStream.Close(); } return returnString; } catch (Exception e) { return "{\"code\":\"-1\",\"msg\":\""+e.Message+"\"}"; } finally { if (res != null) { res.Close(); } } }