net core WebApi——文件分片下載

@[toc]

前言

上一篇net core WebApi——文件分片上傳與跨域請求處理介紹完文件的上傳操作场勤,本來是打算緊接著寫文件下載咨堤,中間讓形形色色的事給耽誤的立倍,今天還是抽個空整理完文件這塊兒镰绎,然后就可以鼓搗別的東西了朝卒。

開始

這里我們仍然使用基礎工程,需要下載的朋友請移步net core Webapi 總目錄香椎,代碼都是與博客的進度基本同步的漱竖。
上傳的時候我們介紹過分片的思路,而下載也一樣畜伐,只是客戶端與服務端角色轉換下就好了馍惹。
后端

  1. 接收前端下載請求,校驗請求信息,返回文件基本信息
  2. 根據前端請求文件片段進行下載流處理万矾。

前端

  1. 向后端發(fā)起下載請求悼吱,獲取文件總片段數
  2. 根據片段數循環(huán)請求文件片段流進行下載(可單獨請求某一片段文件數據)

文件下載相對于上傳來說稍微簡潔點兒,如果不考慮服務器壓力也可以一個a標簽解決下載問題良狈,分片的意義就在于每次與服務端的交互減少流量后添,有些時候我們推薦拿空間換時間,但對于大流量來說還是慢慢來比較好薪丁,單次訪問量如果大再加上多并發(fā)怕是服務器會受不了遇西,所以有了一片片分步來循環(huán)訪問這個方法。

也是直接來看代碼吧严嗜,我們在FileController創(chuàng)建幾個接口方法RequestDownloadFile努溃,FileDownload

        /// <summary>
        /// 請求下載文件
        /// </summary>
        /// <param name="fileInfo">文件參數信息[name]</param>
        /// <returns></returns>
        [HttpPost, Route("RequestDownload")]
        public MessageEntity RequestDownloadFile([FromBody]Dictionary<string, object> fileInfo)
        {

        }

        /// <summary>
        /// 分段下載文件
        /// </summary>
        /// <param name="fileInfo">請求參數信息[index,name]</param>
        /// <returns></returns>
        [HttpPost, Route("Download")]
        public async Task<IActionResult> FileDownload([FromBody]Dictionary<string, object> fileInfo)
        {

        }

RequestDownloadFile

這里說明下阻问,與服務端的操作都要盡可能多的確認身份信息(當然后續(xù)會有說這塊兒),文件的相關操作也一樣需要并且還要嚴格點兒沦疾,我這里就是為了做示例演示所以只傳文件信息即可称近。

        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;
            }
            //獲取對應目錄下文件,如果有哮塞,獲取文件開始準備分段下載
            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},錯誤信息:{ex.Message}");
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                }
            }

            return message;
        }

FileDownload

        public async Task<IActionResult> FileDownload([FromBody]Dictionary<string, object> fileInfo)
        {
            //開始根據片段來下載
            int index = 0;
            if (fileInfo.ContainsKey("index"))
            {
                int.TryParse(fileInfo["index"].ToString(), out index);
            }
            else
            {
                return Ok(new { code = -1, msg = "缺少參數" });
            }
            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 = "文件名不能為空" });
            }
            //獲取對應目錄下文件衡未,如果有缓醋,獲取文件開始準備分段下載
            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 = "無效的下標" });
                }
                fs.Seek(index * shardSize, SeekOrigin.Begin);
                if (index == count - 1)
                {
                    //最后一片 = 總長 - (每次片段大小 * 已下載片段個數)
                    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");
            }
        }

看過上傳的朋友都清楚上傳是三步,請求上傳=>開始上傳=>合并绊诲,而下載只需要兩步送粱,因為合并與否其實不那么重要了,反正文件流都給客戶端了掂之,那邊自己判斷需要重新下載還是下載部分片段都是他們自己的事了(服務端只管賣抗俄,東西有問題自己解決,多理想的狀態(tài))世舰。

測試

搞完之后重新生成动雹,運行之后我們來測試下效果,測試之前不要忘了接口白名單(做過登錄相關的驗證操作的忽略這點)跟压。


測試

這里提示error是因為解析錯誤胰蝠,實際請求下載測試是正常的,如果有異常問題可以與我聯(lián)系姊氓。

小結

文件相關的上傳下載以及常規(guī)信息的操作可以告一段落丐怯,至于下一步鼓搗點兒啥也還沒想好读跷,本來還在看著linux相關的操作做發(fā)布部署的鋪墊,看最近總體的進度吧禾唁,總之,學如逆水行舟荡短,如果不想溺水丐枉,就握好你的漿(當然有些人不用漿那就算了瘦锹,告辭)弯院。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末异赫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子名惩,更是在濱河造成了極大的恐慌,老刑警劉巖弯予,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呼寸,死亡現(xiàn)場離奇詭異对雪,居然都是意外死亡河狐,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門瑟捣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來馋艺,“玉大人,你說我怎么就攤上這事迈套【桁簦” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵桑李,是天一觀的道長踱蛀。 經常有香客問我,道長贵白,這世上最難降的妖魔是什么星岗? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮戒洼,結果婚禮上,老公的妹妹穿的比我還像新娘允华。我一直安慰自己圈浇,他們只是感情好,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布靴寂。 她就那樣靜靜地躺著磷蜀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪百炬。 梳的紋絲不亂的頭發(fā)上褐隆,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天,我揣著相機與錄音剖踊,去河邊找鬼庶弃。 笑死,一個胖子當著我的面吹牛德澈,可吹牛的內容都是我干的歇攻。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼梆造,長吁一口氣:“原來是場噩夢啊……” “哼缴守!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤屡穗,失蹤者是張志新(化名)和其女友劉穎贴捡,沒想到半個月后,有當地人在樹林里發(fā)現(xiàn)了一具尸體村砂,經...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡烂斋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了箍镜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片源祈。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖色迂,靈堂內的尸體忽然破棺而出香缺,到底是詐尸還是另有隱情,我是刑警寧澤歇僧,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布图张,位于F島的核電站,受9級特大地震影響诈悍,放射性物質發(fā)生泄漏祸轮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一侥钳、第九天 我趴在偏房一處隱蔽的房頂上張望适袜。 院中可真熱鬧,春花似錦舷夺、人聲如沸苦酱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疫萤。三九已至,卻和暖如春敢伸,著一層夾襖步出監(jiān)牢的瞬間扯饶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工池颈, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留尾序,地道東北人。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓躯砰,卻偏偏與公主長得像蹲诀,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子弃揽,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內容