目錄

          * 前言 <https://www.cnblogs.com/AprilBlank/p/11419012.html#前言>
          * 開始 <https://www.cnblogs.com/AprilBlank/p/11419012.html#開始>
          * 測試 <https://www.cnblogs.com/AprilBlank/p/11419012.html#測試>
          * 小結(jié) <https://www.cnblogs.com/AprilBlank/p/11419012.html#小結(jié)>
          @

          前言

          上一篇net core WebApi——文件分片上傳與跨域請求處理
          <https://www.cnblogs.com/AprilBlank/p/11399509.html>
          介紹完文件的上傳操作,本來是打算緊接著寫文件下載,中間讓形形色色的事給耽誤的,今天還是抽個(gè)空整理完文件這塊兒,然后就可以鼓搗別的東西了。

          開始

          這里我們?nèi)匀皇褂没A(chǔ)工程,需要下載的朋友請移步net core Webapi 總目錄
          <https://www.cnblogs.com/AprilBlank/p/11282181.html>,代碼都是與博客的進(jìn)度基本同步的。
          上傳的時(shí)候我們介紹過分片的思路,而下載也一樣,只是客戶端與服務(wù)端角色轉(zhuǎn)換下就好了。
          后端

          * 接收前端下載請求,校驗(yàn)請求信息,返回文件基本信息
          * 根據(jù)前端請求文件片段進(jìn)行下載流處理。
          前端

          * 向后端發(fā)起下載請求,獲取文件總片段數(shù)
          * 根據(jù)片段數(shù)循環(huán)請求文件片段流進(jìn)行下載(可單獨(dú)請求某一片段文件數(shù)據(jù))
          文件下載相對于上傳來說稍微簡潔點(diǎn)兒,如果不考慮服務(wù)器壓力也可以一個(gè)a
          標(biāo)簽解決下載問題,分片的意義就在于每次與服務(wù)端的交互減少流量,有些時(shí)候我們推薦拿空間換時(shí)間,但對于大流量來說還是慢慢來比較好,單次訪問量如果大再加上多并發(fā)怕是服務(wù)器會受不了,所以有了一片片分步來循環(huán)訪問這個(gè)方法。

          也是直接來看代碼吧,我們在FileController創(chuàng)建幾個(gè)接口方法RequestDownloadFile,F(xiàn)ileDownload。
          /// <summary> /// 請求下載文件 /// </summary> /// <param
          name="fileInfo">文件參數(shù)信息[name]</param> /// <returns></returns> [HttpPost,
          Route("RequestDownload")] public MessageEntity
          RequestDownloadFile([FromBody]Dictionary<string, object> fileInfo) { } ///
          <summary> /// 分段下載文件 /// </summary> /// <param
          name="fileInfo">請求參數(shù)信息[index,name]</param> /// <returns></returns> [HttpPost,
          Route("Download")] public async Task<IActionResult>
          FileDownload([FromBody]Dictionary<string, object> fileInfo) { }
          RequestDownloadFile


          這里說明下,與服務(wù)端的操作都要盡可能多的確認(rèn)身份信息(當(dāng)然后續(xù)會有說這塊兒),文件的相關(guān)操作也一樣需要并且還要嚴(yán)格點(diǎn)兒,我這里就是為了做示例演示所以只傳文件信息即可。
          public MessageEntity RequestDownloadFile([FromBody]Dictionary<string, object>
          fileInfo) { MessageEntity message = new MessageEntity(); string fileName =
          string.Empty; string fileExt = string.Empty; if (fileInfo.ContainsKey("name"))
          { fileName = fileInfo["name"].ToString(); } if (fileInfo.ContainsKey("ext")) {
          fileExt = fileInfo["ext"].ToString(); } if (string.IsNullOrEmpty(fileName)) {
          message.Code = -1; message.Msg = "文件名不能為空"; return message; }
          //獲取對應(yīng)目錄下文件,如果有,獲取文件開始準(zhǔn)備分段下載 string filePath =
          $".{AprilConfig.FilePath}{DateTime.Now.ToString("yyyy-MM-dd")}/{fileName}";
          filePath = $"{filePath}{fileExt}"; FileStream fs = null; try { if
          (!System.IO.File.Exists(filePath)) { //文件為空 message.Code = -1; message.Msg =
          "文件尚未處理完"; return message; } fs = new FileStream(filePath, FileMode.Open); if
          (fs.Length <= 0) { //文件為空 message.Code = -1; message.Msg = "文件尚未處理完"; return
          message; } int shardSize = 1 * 1024 * 1024;//一次1M RequestFileUploadEntity
          request = new RequestFileUploadEntity(); request.fileext = fileExt;
          request.size = fs.Length; request.count = (int)(fs.Length / shardSize); if
          ((fs.Length % shardSize) > 0) { request.count += 1; } request.filedata =
          GetCryptoString(fs); message.Data = request; } catch (Exception ex) {
          LogUtil.Debug($"讀取文件信息失?。簕filePath},錯(cuò)誤信息:{ex.Message}"); } finally { if (fs !=
          null) { fs.Close(); } } return message; }
          FileDownload
          public async Task<IActionResult> FileDownload([FromBody]Dictionary<string,
          object> fileInfo) { //開始根據(jù)片段來下載 int index = 0; if
          (fileInfo.ContainsKey("index")) { int.TryParse(fileInfo["index"].ToString(),
          out index); } else { return Ok(new { code = -1, msg = "缺少參數(shù)" }); } string
          fileName = string.Empty; string fileExt = string.Empty; if
          (fileInfo.ContainsKey("name")) { fileName = fileInfo["name"].ToString(); } if
          (fileInfo.ContainsKey("ext")) { fileExt = fileInfo["ext"].ToString(); } if
          (string.IsNullOrEmpty(fileName)) { return Ok(new { code = -1, msg = "文件名不能為空"
          }); } //獲取對應(yīng)目錄下文件,如果有,獲取文件開始準(zhǔn)備分段下載 string filePath =
          $".{AprilConfig.FilePath}{DateTime.Now.ToString("yyyy-MM-dd")}/{fileName}";
          filePath = $"{filePath}{fileExt}"; if (!System.IO.File.Exists(filePath)) {
          return Ok(new { code = -1, msg = "文件尚未處理" }); } using (var fs = new
          FileStream(filePath, FileMode.Open)) { if (fs.Length <= 0) { return Ok(new {
          code = -1, msg = "文件尚未處理" }); } int shardSize = 1 * 1024 * 1024;//一次1M int
          count = (int)(fs.Length / shardSize); if ((fs.Length % shardSize) > 0) { count
          += 1; } if (index > count - 1) { return Ok(new { code = -1, msg = "無效的下標(biāo)" }); }
          fs.Seek(index * shardSize, SeekOrigin.Begin); if (index == count - 1) { //最后一片
          = 總長 - (每次片段大小 * 已下載片段個(gè)數(shù)) shardSize = (int)(fs.Length - (shardSize * index)); }
          byte[] datas = new byte[shardSize]; await fs.ReadAsync(datas, 0, datas.Length);
          //fs.Close(); return File(datas, "application/x-gzip"); } }
          看過上傳的朋友都清楚上傳是三步,請求上傳=>開始上傳=>合并
          ,而下載只需要兩步,因?yàn)楹喜⑴c否其實(shí)不那么重要了,反正文件流都給客戶端了,那邊自己判斷需要重新下載還是下載部分片段都是他們自己的事了(服務(wù)端只管賣,東西有問題自己解決,多理想的狀態(tài))。

          測試

          搞完之后重新生成,運(yùn)行之后我們來測試下效果,測試之前不要忘了接口白名單(做過登錄相關(guān)的驗(yàn)證操作的忽略這點(diǎn))。


          這里提示error是因?yàn)榻馕鲥e(cuò)誤,實(shí)際請求下載測試是正常的,如果有異常問題可以與我聯(lián)系。

          小結(jié)

          文件相關(guān)的上傳下載以及常規(guī)信息的操作可以告一段落,至于下一步鼓搗點(diǎn)兒啥也還沒想好,本來還在看著linux相關(guān)的操作做發(fā)布部署的鋪墊,看最近總體的進(jìn)度吧,總之,
          學(xué)如逆水行舟,如果不想溺水,就握好你的漿(當(dāng)然有些人不用漿那就算了,告辭)。

          友情鏈接
          ioDraw流程圖
          API參考文檔
          OK工具箱
          云服務(wù)器優(yōu)惠
          阿里云優(yōu)惠券
          騰訊云優(yōu)惠券
          京東云優(yōu)惠券
          站點(diǎn)信息
          問題反饋
          郵箱:[email protected]
          QQ群:637538335
          關(guān)注微信

                快乐激情五月天 | 大香蕉人人在线 | 色色欧| 大香蕉国产在线看 | 青青草中文字幕在线 |