html5 上传超大文件,HTML5教程 如何拖拽上传大文件

本篇教程探讨了HTML5教程 如何拖拽上传大文件,希望阅读本篇文章以后大家有所收获,帮助大家HTML5+CSS3从入门到精通 。

<

前言:

大文件传输一直是技术上的一大难点。文件过大时,一些性提交所有的内容进内存是不现实的。大文件带来问题还有是否支持断点传输和多文件同时传输。

本文以resumableJs为例,介绍了如何在ASP.NET中实现大文件传输。同时本文利用了Html5的新特性:支持拖拽。

本文的主要技术点在于:如何接收resumableJs的传送内容(官网不太清楚)和如何合并文件,难度并不高。

注:原博客中,此文章为原站点个人代码备份所用,注释不多,如有不懂,请在评论中给出。

效果:

ASPX File:

Resumable.js Test

welcome

var showInfo = function (msg) {

document.getElementById("info").innerHTML = msg;

}

showInfo("Test begin");

var r = new Resumable({

target: ‘FileHandler.ashx‘,

});

r.assignBrowse(document.getElementById(‘container‘));

r.assignDrop(document.getElementById(‘container‘));

if (!r.support) showInfo("not support");

r.on(‘fileAdded‘, function (file, event) {

r.upload();

});

r.on(‘filesAdded‘, function (array) {

for (var i = 0; i 

var html = document.getElementById("info").innerHTML;

html += "
"+array[i].name;

}

});

r.on(‘uploadStart‘, function () {

showInfo(‘start‘);

});

r.on(‘complete‘, function () {

r.files.pop();

//if want to upload one file multiple times, you should remove it from r.files after completing.

//pop后,才可再次重新拖拽上传此文件。此机制可避免一次上传多个文件时重复添加,但拖拽上传时不用检测。

});

r.on(‘progress‘, function (e) {

showInfo(r.progress());

});

FileHandler

using System;

using System.Collections.Generic;

using System.IO;

using System.Linq;

using System.Web;

namespace UploadTest

{

/// 

/// Summary description for FileHandler

/// 

public class FileHandler : IHttpHandler

{

string _tempFolder;

object _lock = new object();

public void ProcessRequest(HttpContext context)

{

_tempFolder = context.Server.MapPath("~/temp");

var method = context.Request.HttpMethod;

if (method.Equals("GET"))

{

HandleGet(context);

}

if (method.Equals("POST"))

{

HandlePost(context);

}

}

private  void HandlePost(HttpContext context)

{

var queryString = context.Request.Form;

if (queryString.Count == 0) return;

try

{

// Read parameters

var uploadToken = queryString.Get("upload_Token");

int resumableChunkNumber = int.Parse(queryString.Get("resumableChunkNumber"));

var resumableTotalChunks = int.Parse(queryString.Get("resumableTotalChunks"));

var resumableTotalSize = long.Parse(queryString.Get("resumableTotalSize"));

var resumableFilename = queryString.Get("resumableFilename");

// Save File

if (context.Request.Files.Count == 0)

{

context.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;

}

else

{

var filePath = string.Format("{0}/{1}/{1}.part{2}", _tempFolder, resumableFilename, resumableChunkNumber.ToString("0000"));

var directory = Path.GetDirectoryName(filePath);

if (File.Exists(directory))

{

File.Delete(directory);

}

if (!Directory.Exists(directory))

{

Directory.CreateDirectory(directory);

}

if (!System.IO.File.Exists(filePath))

{

context.Request.Files[0].SaveAs(filePath);

}

if (IsCompleted(directory,resumableTotalChunks,resumableTotalSize))

{

MergeFiles(directory);

}

}

}

catch (Exception exception)

{

throw exception;

}

}

private void HandleGet(HttpContext context)

{

var queryString = context.Request.QueryString;

if (queryString.Count == 0) return;

try

{

// Read parameters

var uploadToken = queryString.Get("upload_Token");

int resumableChunkNumber = int.Parse(queryString.Get("resumableChunkNumber"));

var resumableFilename = queryString.Get("resumableFilename");

var resumableChunkSize = long.Parse(queryString.Get("resumableChunkSize"));

var filePath = string.Format("{0}/{1}/{1}.part{2}", _tempFolder,

resumableFilename, resumableChunkNumber.ToString("0000"));

// Check for existance and chunksize

if (System.IO.File.Exists(filePath) && new FileInfo(filePath).Length == resumableChunkSize)

{

context.Response.Status = "200 OK";

context.Response.StatusCode = 200;

}

else

{

context.Response.Status = "404 Not Found";

context.Response.StatusCode = 404;

}

}

catch (Exception exception)

{

throw exception;

}

}

private bool IsCompleted(string directory,int numChunks, long totalSize )

{

var physicalFolder = Path.Combine(_tempFolder, directory);

var files = Directory.GetFiles(physicalFolder);

//numbers

if (files.Length != numChunks)

return false;

//files all exisit

var fileName = Path.GetFileName(directory);

for (int i = 1; i <= numChunks; i++)

{

var filePath = string.Format("{0}/{1}.part{2}", directory, fileName, i.ToString("0000"));

if (!File.Exists(filePath))

{

return false;

}

}

//size

long tmpSize = 0;

foreach (var file in files)

{

tmpSize += new FileInfo(file).Length;

}

return totalSize==tmpSize;

}

private void MergeFiles(string directoryPath)

{

lock (_lock)

{

if (Directory.Exists(directoryPath))

{

var fileName = Path.GetFileName(directoryPath);

var folder = Path.GetDirectoryName(directoryPath);

var tempPath = Path.Combine(directoryPath + ".tmp");

var files = Directory.GetFiles(directoryPath);

files = files.OrderBy(f => f).ToArray();

FileStream wholeStream = new FileStream(tempPath, FileMode.Append, FileAccess.Write);

for(int i=0;i

{

FileStream parcialStream = new FileStream(files[i], FileMode.Open);

BinaryReader parcialReader = new BinaryReader(parcialStream);

byte[] buffer = new byte[parcialStream.Length];

buffer = parcialReader.ReadBytes((int)parcialStream.Length);

BinaryWriter parcialWriter = new BinaryWriter(wholeStream);

parcialWriter.Write(buffer);

parcialStream.Close();

}

wholeStream.Close();

Directory.Delete(directoryPath,true);

File.Move(tempPath, directoryPath);

}

}

}

public bool IsReusable

{

get

{

return false;

}

}

}

}

附录:

1 技术难点

a. 文件过大。修改webconfig无用。

b. 断点续传。

c. 多文件上传。

2 resumable.js

API: http://www.resumablejs.com/

工作流程:

拖文件至DIV -> 开始上传,uploadStart -> 反复触发progress事件 -> compete

主要参数:

Get:

resumableChunkNumber=1&

resumableChunkSize=1048576&

resumableCurrentChunkSize=1048576&

resumableTotalSize=27778318&

resumableType=&

resumableIdentifier=27778318-Samples7z&

resumableFilename=Samples.7z&

resumableRelativePath=Samples.7z&

resumableTotalChunks=26

Post:

—————————–111061030216033

Content-Disposition: form-data; name=”resumableChunkNumber”

140

—————————–111061030216033

Content-Disposition: form-data; name=”resumableChunkSize”

1048576

—————————–111061030216033

Content-Disposition: form-data; name=”resumableCurrentChunkSize”

1048576

—————————–111061030216033

Content-Disposition: form-data; name=”resumableTotalSize”

171309601

—————————–111061030216033

Content-Disposition: form-data; name=”resumableType”

—————————–111061030216033

Content-Disposition: form-data; name=”resumableIdentifier”

171309601-sample7z

—————————–111061030216033

Content-Disposition: form-data; name=”resumableFilename”

sample.7z

—————————–111061030216033

Content-Disposition: form-data; name=”resumableRelativePath”

sample.7z

—————————–111061030216033

Content-Disposition: form-data; name=”resumableTotalChunks”

163

—————————–111061030216033

Content-Disposition: form-data; name=”file”; filename=”blob”

Content-Type: application/octet-stream

XXXCONTENT

—————————–309022088923579–

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标WEB前端HTML5/CSS3频道!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HTML5实现拖拽批量上传文件的代码如下: ```html <!DOCTYPE html> <html> <head> <title>Drag and Drop File Upload</title> <style> #drop_area { width: 200px; height: 200px; border: 2px dashed gray; text-align: center; font-size: 20px; margin: 20px auto; padding: 10px; } </style> </head> <body> <div id="drop_area"> Drag and Drop Files Here </div> <script> var dropArea = document.getElementById('drop_area'); // Prevent default drag behaviors ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { dropArea.addEventListener(eventName, preventDefaults, false); document.body.addEventListener(eventName, preventDefaults, false); }); // Highlight drop area when dragging files over it ['dragenter', 'dragover'].forEach(eventName => { dropArea.addEventListener(eventName, highlight, false); }); // Remove highlight when dragging files out of drop area ['dragleave', 'drop'].forEach(eventName => { dropArea.addEventListener(eventName, unhighlight, false); }); // Handle dropped files dropArea.addEventListener('drop', handleDrop, false); function preventDefaults(e) { e.preventDefault(); e.stopPropagation(); } function highlight() { dropArea.classList.add('highlight'); } function unhighlight() { dropArea.classList.remove('highlight'); } function handleDrop(e) { var dt = e.dataTransfer; var files = dt.files; handleFiles(files); } function handleFiles(files) { files = [...files]; files.forEach(uploadFile); } function uploadFile(file) { var url = 'upload.php'; var formData = new FormData(); formData.append('file', file); fetch(url, { method: 'POST', body: formData }) .then(response => { console.log(response.text()); }) .catch(error => { console.error(error); }); } </script> </body> </html> ``` 其中,`upload.php` 是接收文件并处理的 PHP 文件。下面是一个简单的上传 PHP 文件的示例: ```php <?php if ($_FILES['file']['error'] === UPLOAD_ERR_OK) { $uploadPath = './uploads/' . basename($_FILES['file']['name']); move_uploaded_file($_FILES['file']['tmp_name'], $uploadPath); echo 'File uploaded successfully!'; } else { echo 'Error uploading file.'; } ?> ``` 上述代码将上传文件保存到 `uploads` 文件夹中,并返回上传成功或失败的消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值