在使用騰訊云對象存儲之前,公司一直使用的是傳統(tǒng)的FTP的上傳模式,而隨著用戶量的不斷增加,F(xiàn)TP所暴露出來的問題也越來越多,1.傳輸效率低,上傳速度慢。2.時常有上傳其他文件來攻擊服務(wù)器,安全上得不到保障。所以我們在經(jīng)過慎重考慮覺得使用第三方的云存儲服務(wù)。
在最開始的時候我們在騰訊云與阿里云中選擇,最終我們選擇騰訊云,騰訊云在文件上傳用時方面的性能比較突出,文件越大表現(xiàn)越好;在下載用時方面表現(xiàn)略優(yōu)于阿里云;文件刪除用時方面總體速度略遜于,但在不同大小文件刪除用時上都比較穩(wěn)定。當(dāng)然這與我們主要用于開發(fā)微信小程序是有著密切的關(guān)系。
在我們酷客多小程序使用騰訊云對象存儲的時候除了直接使用 API 接口外,COS 提供了豐富多樣的 SDK 給我們使用,可是在他提供的SDK中并沒有發(fā)現(xiàn)我們Asp.net相關(guān)的SDK
在一番百度和一頓操作終于讓我找到啦!看到?jīng)],只能說隱藏的真深,而且還是歷史版本的,但是不管怎么樣我們還是找到啦
找到C#的SDK,下載下來 (附上C#版本SDK的下載地址 C# SDK github項(xiàng)目下載地址)然后按照SDK中提供的方法,就可以成功上傳!
然而并沒有這么簡單,當(dāng)我們使用SDK中的方法的時候發(fā)現(xiàn),SDK中的方法只適用于,絕對路徑地址的文件上傳!也就是并不滿足我們ASP.Net中使用文件域上傳文件。此時我們只有對方法進(jìn)行改造!
附上改造過后代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
|
/// <summary> /// 文件流上傳 /// 說明: 酷客多小程序 /// 其中分片上傳使用SliceUploadInit SliceUploadData SliceUploadFinihs /// </summary> /// <param name="bucketName">bucket名稱</param> /// <param name="remotePath">遠(yuǎn)程文件路徑</param> /// <param name="localPath">本地文件路徑</param> /// <param name="parameterDic">參數(shù)Dictionary</param> /// <returns></returns> public string UploadFile( string bucketName, string remotePath, Stream file, string filename,Dictionary< string , string > parameterDic = null ) { if (remotePath.EndsWith( "/" )) { return constructResult(ERRORCode.ERROR_CODE_PARAMETER_ERROE, "file path can not end with '/'" ); } string bizAttribute = "" ; if (parameterDic != null && parameterDic.ContainsKey(CosParameters.PARA_BIZ_ATTR)) bizAttribute = parameterDic[CosParameters.PARA_BIZ_ATTR]; int insertOnly = 1; if (parameterDic != null && parameterDic.ContainsKey(CosParameters.PARA_INSERT_ONLY)) { try { insertOnly = Int32.Parse(parameterDic[CosParameters.PARA_INSERT_ONLY]); } catch (Exception e) { Console.WriteLine(e.Message); return constructResult(ERRORCode.ERROR_CODE_PARAMETER_ERROE, "parameter insertOnly value invalidate" ); } } return Upload(bucketName, remotePath, file, filename, bizAttribute, insertOnly); } /// <summary> /// 單個文件上傳 /// 說明: 酷客多小程序 /// <param name="bucketName">bucket名稱</param> /// <param name="remotePath">遠(yuǎn)程文件路徑</param> /// <param name="localPath">本地文件路徑</param> /// <param name="biz_attr">biz_attr屬性</param> /// <param name="insertOnly">同名文件是否覆蓋</param> /// <returns></returns> public string Upload( string bucketName, string remotePath, Stream file, string filename, string bizAttribute = "" , int insertOnly = 1) { var url = generateURL(bucketName, remotePath); var sha1 = SHA1.GetFileSHA1(file); var data = new Dictionary< string , object >(); data.Add( "op" , "upload" ); data.Add( "sha" , sha1); data.Add( "biz_attr" , bizAttribute); data.Add( "insertOnly" , insertOnly); var expired = getExpiredTime(); var sign = Sign.Signature(appId, secretId, secretKey, expired, bucketName); var header = new Dictionary< string , string >(); header.Add( "Authorization" , sign); return httpRequest.SendRequest(url, ref data, HttpMethod.Post, ref header, timeOut, file, filename); } #region 直接上傳文件流 public string SendRequest( string url, ref Dictionary< string , object > data, HttpMethod requestMethod, ref Dictionary< string , string > header, int timeOut, Stream file, string filename, long offset = -1, int sliceSize = 0) { try { //Console.WriteLine("url:" + url); System.Net.ServicePointManager.Expect100Continue = false ; if (requestMethod == HttpMethod.Get) { var paramStr = "" ; foreach (var key in data.Keys) { paramStr += string .Format( "{0}={1}&" , key, HttpUtility.UrlEncode(data[key].ToString())); } paramStr = paramStr.TrimEnd( '&' ); url += (url.EndsWith( "?" ) ? "&" : "?" ) + paramStr; } request = (HttpWebRequest)HttpWebRequest.Create(url); request.Accept = CosDefaultValue.ACCEPT; request.KeepAlive = true ; request.UserAgent = CosDefaultValue.USER_AGENT_VERSION; request.Timeout = timeOut; foreach (var key in header.Keys) { if (key == "Content-Type" ) { request.ContentType = header[key]; } else { request.Headers.Add(key, header[key]); } } if (requestMethod == HttpMethod.Post) { request.Method = requestMethod.ToString().ToUpper(); var memStream = new MemoryStream(); if (header.ContainsKey( "Content-Type" ) && header[ "Content-Type" ] == "application/json" ) { var json = JsonConvert.SerializeObject(data); var jsonByte = Encoding.GetEncoding( "utf-8" ).GetBytes(json.ToString()); memStream.Write(jsonByte, 0, jsonByte.Length); } else { var boundary = "---------------" + DateTime.Now.Ticks.ToString( "x" ); var beginBoundary = Encoding.ASCII.GetBytes( "\r\n--" + boundary + "\r\n" ); var endBoundary = Encoding.ASCII.GetBytes( "\r\n--" + boundary + "--\r\n" ); request.ContentType = "multipart/form-data; boundary=" + boundary; var strBuf = new StringBuilder(); foreach (var key in data.Keys) { strBuf.Append( "\r\n--" + boundary + "\r\n" ); strBuf.Append( "Content-Disposition: form-data; name=\"" + key + "\"\r\n\r\n" ); strBuf.Append(data[key].ToString()); } var paramsByte = Encoding.GetEncoding( "utf-8" ).GetBytes(strBuf.ToString()); memStream.Write(paramsByte, 0, paramsByte.Length); memStream.Write(beginBoundary, 0, beginBoundary.Length); var fileStream = file; const string filePartHeader = "Content-Disposition: form-data; name=\"fileContent\"; filename=\"{0}\"\r\n" + "Content-Type: application/octet-stream\r\n\r\n" ; var headerText = string .Format(filePartHeader, filename); var headerbytes = Encoding.UTF8.GetBytes(headerText); memStream.Write(headerbytes, 0, headerbytes.Length); if (offset == -1) { var buffer = new byte [1024]; int bytesRead; while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) { memStream.Write(buffer, 0, bytesRead); } } else { var buffer = new byte [sliceSize]; int bytesRead; fileStream.Seek(offset, SeekOrigin.Begin); bytesRead = fileStream.Read(buffer, 0, buffer.Length); memStream.Write(buffer, 0, bytesRead); } fileStream.Close(); memStream.Write(endBoundary, 0, endBoundary.Length); } request.ContentLength = memStream.Length; var requestStream = request.GetRequestStream(); memStream.Position = 0; var tempBuffer = new byte [memStream.Length]; memStream.Read(tempBuffer, 0, tempBuffer.Length); memStream.Close(); requestStream.Write(tempBuffer, 0, tempBuffer.Length); requestStream.Close(); //Console.WriteLine(strBuf.ToString()); } //Console.WriteLine(request.ContentType.ToString()); var response = request.GetResponse(); using (var s = response.GetResponseStream()) { var reader = new StreamReader(s, Encoding.UTF8); return reader.ReadToEnd(); } } catch (WebException we) { if (we.Status == WebExceptionStatus.ProtocolError) { using (var s = we.Response.GetResponseStream()) { var reader = new StreamReader(s, Encoding.UTF8); return reader.ReadToEnd(); } } else { throw we; } } catch (Exception e) { throw e; } } |
使用上面改造過后的方法直接傳入文件流即可通過文本域的方式上傳文件到騰訊云上面去!
總結(jié)
以上所述是小編給大家介紹的微信小程序基于騰訊云對象存儲的圖片上傳功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對服務(wù)器之家網(wǎng)站的支持!
原文鏈接:https://www.cnblogs.com/ywqu/archive/2018/03/19/8604821.html