

但是,即使把服务器的配置中的上传文件大小写的够大,又会受到IIS的,而且也不能为用户提供安全的服务。那有没有一种方法能解决大文件上传的问题呢?
肯定是有的:分片上传。
分片上传是指将想要上传的文件在前端切割成大小很小的小块,然后再传给服务器,从服务器端再将文件组合成整的文件。
先从前端说起,在分片上传的过程中,前端任务是将文件分片,分片的办法有很多,例如可以使用WebUpLoader提供的上传组件进行分片,也可以用JS与JQ提供的代码进行上传,代码实例如下:
var BYTES_PER_CHUNK = 1024 * 1024; // 每个文件切片大小定为1MB .
var slices;
var totalSlices;
//发送请求
function sendRequest() {
var blob = document.getElementById("yourID").files[0];
var start = 0;
var end;
var index = 0;
// 计算文件切片总数
slices = Math.ceil(blob.size / BYTES_PER_CHUNK);
totalSlices= slices;
while(start < blob.size) {
end = start + BYTES_PER_CHUNK;
if(end > blob.size) {
end = blob.size;
}
uploadFile(blob, index, start, end);
start = end;
index++;
if ( index>=totalSlices )
alert("Complete!!");
}
}
//上传文件
function uploadFile(blob, index, start, end) {
var xhr;
var fd;
var chunk;
var sliceIndex=blob.name+index;
chunk =blob.slice(start,end);//切割文件
fd = new FormData();
fd.append("FileName", chunk, sliceIndex);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'Server URL', false);//false,同步上传;ture,异步上传
xhr.send(fd);
if((xhr.status >=200 && xhr.status < 300) || xhr.status == 304){
setTimeout("",10);
}else{
uploadFile(blob, index, start, end);
}
}有了前端,当然少不了在后端的接受与组合,在这里我用ASP.Net为例,说明如何接收与组合文件。
public void RecoveryKPJD()
{
HttpContext context = System.Web.HttpContext.Current;
context.Response.ContentType = "text/plain";
//如果进行了分片
if (context.Request.Form.AllKeys.Any(m => m == "chunk"))
{
//取得chunk和chunks
int chunk = Convert.ToInt32(context.Request.Form["chunk"]);//当前分片在上传分片中的顺序(从0开始)
int chunks = Convert.ToInt32(context.Request.Form["chunks"]);//总分片数
//根据GUID创建用该GUID命名的临时文件夹
string folder = Your Path + context.Request["guid"] + "/";
string path = folder + chunk;
//建立临时传输文件夹
if (!Directory.Exists(Path.GetDirectoryName(folder)))
{
Directory.CreateDirectory(folder);
}
FileStream addFile = new FileStream(path, FileMode.Append, FileAccess.Write);
BinaryWriter AddWriter = new BinaryWriter(addFile);
//获得上传的分片数据流
HttpPostedFile file = context.Request.Files[0];
Stream stream = file.InputStream;
BinaryReader TempReader = new BinaryReader(stream);
//将上传的分片追加到临时文件末尾
AddWriter.Write(TempReader.ReadBytes((int)stream.Length));
//关闭BinaryReader文件阅读器
TempReader.Close();
stream.Close();
AddWriter.Close();
addFile.Close();
TempReader.Dispose();
stream.Dispose();
AddWriter.Dispose();
addFile.Dispose();
if (chunk == chunks - 1)
{
//合并文件
ProcessRequest(context.Request["guid"], Path.GetExtension(file.FileName));
}
}
else//没有分片直接保存
{
string targetPath = ""; //此处写文件的保存路径
context.Request.Files[0].SaveAs(targetPath);
}
}
private void ProcessRequest(string guid, string fileExt)
{
HttpContext context = System.Web.HttpContext.Current;
context.Response.ContentType = "text/plain";
string sourcePath = Path.Combine("Your Path", guid + "/");//源数据文件夹
string targetPath = Path.Combine("Your Path", Guid.NewGuid() + fileExt);//合并后的文件
DirectoryInfo dicInfo = new DirectoryInfo(sourcePath);
if (Directory.Exists(Path.GetDirectoryName(sourcePath)))
{
FileInfo[] files = dicInfo.GetFiles();
foreach (FileInfo file in files.OrderBy(f => int.Parse(f.Name)))
{
FileStream addFile = new FileStream(targetPath, FileMode.AppenFileAccess.Write);
BinaryWriter AddWriter = new BinaryWriter(addFile);
//获得上传的分片数据流
Stream stream = file.Open(FileMode.Open);
BinaryReader TempReader = new BinaryReader(stream);
//将上传的分片追加到临时文件末尾
AddWriter.Write(TempReader.ReadBytes((int)stream.Length));
//关闭BinaryReader文件阅读器
TempReader.Close();
stream.Close();
AddWriter.Close();
addFile.Close();
TempReader.Dispose();
stream.Dispose();
AddWriter.Dispose();
addFile.Dispose();
}
}
}