最近闲余时间在做一个仿百度网盘的项目,其中就有一个上传文件夹的功能。查了下网上好像对这个问题的描述比较少,所以在此记录一下。
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 - ].ToString();//该文件名
for (int i=;i<arrpath.Length;i++)
{
if(i==arrpath.Length-)
{
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(这个是在二级文件夹里的)。
大概的思路就是:获取到文件集合后遍历,然后取得该文件所在的文件夹,如果服务器上不存在该文件夹则创建,最后上传文件。
当然我代码只是写了最基本的实现,具体还有些验证或者业务逻辑还得具体分析。
然后其他就不多说了吧,不太明白的调试下代码差不多就懂了,如有错误,望指出。