最近閑余時間在做一個仿百度網盤的項目,其中就有一個上傳文件夾的功能。查了下網上好像對這個問題的描述比較少,所以在此記錄一下。
1、網上找來找去發現webkitdirectory這個東西,H5的一個新的屬性吧,就是在文件控件上標記這個屬性可以獲取到選擇文件夾里的所有文件的。
<input type="file" name="file" webkitdirectory>
特地看了下百度網盤網頁版也是使用的這個屬性,但是網上都說該屬性只有chrome瀏覽器支持。然后我就不信,用360瀏覽器試了試還是可以用。結果發現360有兩種模式(極速模式和兼容模式),極速模式是以Blink(Webkit)為內核的瀏覽模式,而chrome好像也是使用的這個內核。所以說我剛剛試的也可以用,但是切換到兼容模式則不能用了(IE內核)。
2、言歸正傳,直接貼代碼吧。
<input type="file" name="file" webkitdirectory> <button id="upload" type="button" onclick="Upload()" >上傳</button>
var files = []; $(document).ready(function () { $('input').change(function () { files = this.files; }) }); function Upload() { var data = new FormData(); debugger for (var i = 0; i < files.length; i++) { data.append('file', files[i]); } var path = files[0].webkitRelativePath; $.ajax({ type: "post", url: "/home/UpLoad", data: data, contentType: false, processData: false, success: function (data) { console.log(data); } }) }
最后是控制器
[HttpPost] public IActionResult UpLoad() { var files = Request.Form.Files; string rootpath = _hostingEnvironment.WebRootPath + @"\Files"; try { foreach (var file in files) { string[] arrpath = file.FileName.Split(@"/"); string dirpath = "";//該文件的所在目錄(包括一、二級目錄) string filename = arrpath[arrpath.Length - 1].ToString();//該文件名 for (int i=0;i<arrpath.Length;i++) { if(i==arrpath.Length-1) { break; } dirpath += arrpath[i]+@"/"; } DicCreate(Path.Combine(rootpath, dirpath));//不存在則創建該目錄 string filepath = Path.Combine(rootpath, file.FileName); using (var addFile = new FileStream(filepath, FileMode.OpenOrCreate)) { if (file != null) { file.CopyTo(addFile); } else { Request.Body.CopyTo(addFile); } addFile.Close(); } } return Ok(new { success = true, message = "上傳成功" }); } catch(Exception ex) { return Ok(new { success = false, message = ex.Message }); } } /// <summary> /// 文件目錄如果不存在,就創建一個新的目錄 /// </summary> /// <param name="path"></param> private void DicCreate(string path) { if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } }
3、說明下,后端接收到的files是選擇文件夾里所有文件的集合。
比如我這里測試使用的是選中一個名為新建文件夾的文件夾,然后該文件夾里有兩張圖片和一個子文件夾,子文件夾里也是一張圖片。
所有我獲取到的files是count為3的集合,文件名分別為 新建文件夾/1.jpg、新建文件夾/2.jpg、新建文件夾/新建文件夾/8.jpg(這個是在二級文件夾里的)。
大概的思路就是:獲取到文件集合后遍歷,然后取得該文件所在的文件夾,如果服務器上不存在該文件夾則創建,最后上傳文件。
當然我代碼只是寫了最基本的實現,具體還有些驗證或者業務邏輯還得具體分析。
然后其他就不多說了吧,不太明白的調試下代碼差不多就懂了,如有錯誤,望指出。