河南手机网站建设公司排名水利枢纽门户网站建设方案

张小明 2026/1/5 12:49:59
河南手机网站建设公司排名,水利枢纽门户网站建设方案,建设官方网站企业官网,新浪 sae wordpress开发日记#xff1a;大文件上传系统的探索与实现 2024年5月15日 星期一 晴 今天接到一个颇具挑战性的项目需求#xff1a;开发一个支持20G大文件上传的系统#xff0c;要求包含文件和文件夹上传功能#xff0c;并保留文件夹层级结构。更复杂的是#xff0c;系统需要支持…开发日记大文件上传系统的探索与实现2024年5月15日 星期一 晴今天接到一个颇具挑战性的项目需求开发一个支持20G大文件上传的系统要求包含文件和文件夹上传功能并保留文件夹层级结构。更复杂的是系统需要支持从IE8到现代浏览器的全兼容还要适配国产信创环境。作为广西的一名个人开发者我既兴奋又感到压力山大。技术选型经过一番调研我决定采用以下技术栈前端Vue3 CLI WebUploader百度开源组件后端ASP.NET WebForm考虑到客户已有.NET环境数据库SQL Server客户指定存储阿里云OSS后续可扩展其他云存储文件夹上传的挑战WebUploader默认不支持文件夹上传需要额外处理。我找到了一个基于WebUploader的扩展方案但测试后发现对IE8的支持不够完善。看来需要自己动手改造了。2023年5月16日 星期二 多云前端实现首先搭建Vue3项目结构vue create file-uploader cd file-uploader npm install webuploader --save创建自定义的文件夹上传组件FolderUploader.vueimport WebUploader from webuploader import webuploader/dist/webuploader.css export default { name: FolderUploader, mounted() { this.initUploader() }, methods: { initUploader() { const uploader WebUploader.create({ auto: false, swf: /path/to/Uploader.swf, server: /api/upload, pick: { id: #picker, multiple: true, // 启用文件夹选择非标准API部分浏览器支持 directory: true }, compress: false, chunked: true, chunkSize: 5 * 1024 * 1024, // 5MB分片 threads: 3, formData: { // 可添加额外参数 } }) // 处理文件夹结构 uploader.on(beforeFileQueued, file { // 解析文件夹路径非标准属性部分浏览器支持 if (file._relativePath) { file.relativePath file._relativePath } return true }) // 文件加入队列 uploader.on(fileQueued, file { this.$emit(file-added, file) }) // 上传进度 uploader.on(uploadProgress, (file, percentage) { this.$emit(progress, { file, percentage }) }) // 上传成功 uploader.on(uploadSuccess, (file, response) { this.$emit(success, { file, response }) }) // 上传错误 uploader.on(uploadError, (file, reason) { this.$emit(error, { file, reason }) }) // 绑定开始按钮 document.getElementById(ctlBtn).addEventListener(click, () { uploader.upload() }) this.uploader uploader } }, beforeUnmount() { if (this.uploader) { this.uploader.destroy() } } } .wu-example { position: relative; padding: 45px 15px 15px; margin: 15px 0; background-color: #fafafa; box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.05); border-color: #e5e5e5 #eee #eee; border-style: solid; border-width: 1px 0; }IE8兼容性处理WebUploader在IE8下需要Flash支持我添加了降级方案// 在initUploader方法中添加if(WebUploader.Browser.ieWebUploader.Browser.version8){uploader.option(swf,/path/to/Uploader_ie8.swf)// IE8下禁用文件夹选择不支持uploader.option(pick).directoryfalse}2023年5月17日 星期三 阵雨后端实现ASP.NET WebForm创建文件上传处理页面UploadHandler.ashx% WebHandler LanguageC# ClassUploadHandler % using System; using System.Web; using System.IO; using System.Data.SqlClient; using System.Configuration; public class UploadHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType text/plain; try { HttpPostedFile file context.Request.Files[file]; string relativePath context.Request.Form[relativePath]; string chunk context.Request[chunk]; string chunks context.Request[chunks]; string fileName context.Request[name]; // 如果没有分片信息就是普通上传 if (string.IsNullOrEmpty(chunk)) { SaveFile(file, relativePath); context.Response.Write({\status\: \success\}); return; } // 分片上传处理 int chunkNumber int.Parse(chunk); int totalChunks int.Parse(chunks); string tempDir context.Server.MapPath(~/App_Data/UploadTemp/ fileName); if (!Directory.Exists(tempDir)) { Directory.CreateDirectory(tempDir); } string tempFilePath Path.Combine(tempDir, chunkNumber.ToString()); file.SaveAs(tempFilePath); // 如果是最后一个分片合并文件 if (chunkNumber totalChunks - 1) { string finalPath context.Server.MapPath(~/Uploads/ (string.IsNullOrEmpty(relativePath) ? : relativePath /) fileName); // 确保目录存在 string finalDir Path.GetDirectoryName(finalPath); if (!Directory.Exists(finalDir)) { Directory.CreateDirectory(finalDir); } // 合并分片 using (FileStream fs new FileStream(finalPath, FileMode.Create)) { for (int i 0; i totalChunks; i) { byte[] bytes File.ReadAllBytes(Path.Combine(tempDir, i.ToString())); fs.Write(bytes, 0, bytes.Length); } } // 删除临时目录 Directory.Delete(tempDir, true); // 记录到数据库 SaveToDatabase(fileName, relativePath, finalPath, file.ContentType, file.ContentLength); } context.Response.Write({\status\: \success\, \chunk\: chunk }); } catch (Exception ex) { context.Response.Write({\status\: \error\, \message\: \ ex.Message \}); } } private void SaveFile(HttpPostedFile file, string relativePath) { string uploadFolder HttpContext.Current.Server.MapPath(~/Uploads/); string filePath Path.Combine(uploadFolder, (string.IsNullOrEmpty(relativePath) ? : relativePath /) Path.GetFileName(file.FileName)); // 确保目录存在 string directory Path.GetDirectoryName(filePath); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } file.SaveAs(filePath); // 记录到数据库 SaveToDatabase(file.FileName, relativePath, filePath, file.ContentType, file.ContentLength); } private void SaveToDatabase(string fileName, string relativePath, string filePath, string contentType, long fileSize) { string connStr ConfigurationManager.ConnectionStrings[DefaultConnection].ConnectionString; using (SqlConnection conn new SqlConnection(connStr)) { string sql INSERT INTO UploadedFiles (FileName, RelativePath, FilePath, ContentType, FileSize, UploadTime) VALUES (FileName, RelativePath, FilePath, ContentType, FileSize, UploadTime); SqlCommand cmd new SqlCommand(sql, conn); cmd.Parameters.AddWithValue(FileName, fileName); cmd.Parameters.AddWithValue(RelativePath, relativePath ?? ); cmd.Parameters.AddWithValue(FilePath, filePath); cmd.Parameters.AddWithValue(ContentType, contentType); cmd.Parameters.AddWithValue(FileSize, fileSize); cmd.Parameters.AddWithValue(UploadTime, DateTime.Now); conn.Open(); cmd.ExecuteNonQuery(); } } public bool IsReusable { get { return false; } } }2023年5月18日 星期四 晴数据库设计创建SQL Server表结构CREATETABLEUploadedFiles(IdINTIDENTITY(1,1)PRIMARYKEY,FileName NVARCHAR(255)NOTNULL,RelativePath NVARCHAR(1000),FilePath NVARCHAR(1000)NOTNULL,ContentType NVARCHAR(100),FileSizeBIGINTNOTNULL,UploadTimeDATETIMENOTNULL,IsFolderBITDEFAULT0,ParentIdINTNULL,FOREIGNKEY(ParentId)REFERENCESUploadedFiles(Id));文件夹结构处理修改前端上传逻辑添加文件夹标记// 在fileQueued事件处理中添加uploader.on(fileQueued,file{// 如果是文件夹通过文件大小为0判断if(file.size0file.name.indexOf(.)-1){file.isFoldertrue// 在数据库中记录文件夹this.saveFolderToDatabase(file)}this.$emit(file-added,file)})// 在methods中添加asyncsaveFolderToDatabase(folder){try{constresponseawaitfetch(/api/saveFolder,{method:POST,headers:{Content-Type:application/json},body:JSON.stringify({name:folder.name,relativePath:folder.relativePath||})})constresultawaitresponse.json()if(result.statussuccess){folder.databaseIdresult.id}}catch(error){console.error(保存文件夹失败:,error)}}2023年5月19日 星期五 多云下载功能实现创建下载处理页面DownloadHandler.ashx% WebHandler LanguageC# ClassDownloadHandler % using System; using System.Web; using System.IO; using System.Data.SqlClient; using System.Configuration; public class DownloadHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { int fileId; if (!int.TryParse(context.Request.QueryString[id], out fileId)) { context.Response.StatusCode 400; context.Response.Write(无效的文件ID); return; } // 从数据库获取文件信息 string connStr ConfigurationManager.ConnectionStrings[DefaultConnection].ConnectionString; string filePath ; string fileName ; bool isFolder false; using (SqlConnection conn new SqlConnection(connStr)) { string sql SELECT FilePath, FileName, IsFolder FROM UploadedFiles WHERE Id Id; SqlCommand cmd new SqlCommand(sql, conn); cmd.Parameters.AddWithValue(Id, fileId); conn.Open(); SqlDataReader reader cmd.ExecuteReader(); if (reader.Read()) { filePath reader[FilePath].ToString(); fileName reader[FileName].ToString(); isFolder Convert.ToBoolean(reader[IsFolder]); } reader.Close(); } if (isFolder) { // 如果是文件夹打包下载 string zipPath context.Server.MapPath(~/App_Data/Temp/ Guid.NewGuid() .zip); System.IO.Compression.ZipFile.CreateFromDirectory(filePath, zipPath); context.Response.Clear(); context.Response.ContentType application/zip; context.Response.AddHeader(Content-Disposition, attachment; filename\ HttpUtility.UrlEncode(fileName .zip) \); context.Response.WriteFile(zipPath); context.Response.Flush(); // 删除临时zip文件 File.Delete(zipPath); } else if (File.Exists(filePath)) { // 普通文件下载 context.Response.Clear(); context.Response.ContentType application/octet-stream; context.Response.AddHeader(Content-Disposition, attachment; filename\ HttpUtility.UrlEncode(fileName) \); context.Response.WriteFile(filePath); context.Response.Flush(); } else { context.Response.StatusCode 404; context.Response.Write(文件不存在); } } public bool IsReusable { get { return false; } } }2023年5月20日 星期六 晴加密传输实现添加SM4和AES加密支持前端使用crypto-js库npm install crypto-js --save修改上传逻辑importCryptoJSfromcrypto-js// 在initUploader方法中添加加密选项constencryptOption{enabled:true,algorithm:SM4,// 或 AESkey:your-secret-key-1234567890,// 实际项目中应从安全配置获取iv:your-iv-123456// 初始化向量}// 修改上传前的处理uploader.on(beforeFileQueued,file{if(encryptOption.enabled){file.encryptencryptOption}// ...原有代码})// 添加加密过滤器uploader.on(uploadBeforeSend,(block,data){if(block.file.encrypt){const{algorithm,key,iv}block.file.encrypt// 读取文件内容需要使用FileReaderconstreadernewFileReader()reader.onloade{letencryptedif(algorithmSM4){// 实际项目中应使用支持SM4的库这里简化处理encryptedCryptoJS.AES.encrypt(CryptoJS.lib.WordArray.create(e.target.result),CryptoJS.enc.Utf8.parse(key),{iv:CryptoJS.enc.Utf8.parse(iv)}).toString()}else{// AESencryptedCryptoJS.AES.encrypt(CryptoJS.lib.WordArray.create(e.target.result),CryptoJS.enc.Utf8.parse(key),{iv:CryptoJS.enc.Utf8.parse(iv)}).toString()}// 替换原始数据block.blobnewBlob([encrypted],{type:block.file.type})block.sizeblock.blob.size}reader.readAsArrayBuffer(block.blob)}})后端解密处理在UploadHandler.ashx中添加private byte[] DecryptFile(byte[] encryptedData, string algorithm, string key, string iv) { try { if (algorithm SM4) { // 实际项目中应使用支持SM4的库这里简化处理 // 注意.NET默认不支持SM4需要引入第三方库 return encryptedData; // 临时返回加密数据实际应解密 } else // AES { using (Aes aesAlg Aes.Create()) { aesAlg.Key Encoding.UTF8.GetBytes(key); aesAlg.IV Encoding.UTF8.GetBytes(iv); using (MemoryStream msDecrypt new MemoryStream(encryptedData)) using (CryptoStream csDecrypt new CryptoStream( msDecrypt, aesAlg.CreateDecryptor(), CryptoStreamMode.Read)) using (MemoryStream msResult new MemoryStream()) { csDecrypt.CopyTo(msResult); return msResult.ToArray(); } } } } catch { return encryptedData; // 解密失败返回原始数据 } } // 修改SaveFile方法在保存前解密 private void SaveFile(HttpPostedFile file, string relativePath) { // ...原有代码 // 读取上传的数据 byte[] fileData; using (BinaryReader reader new BinaryReader(file.InputStream)) { fileData reader.ReadBytes(file.ContentLength); } // 如果有加密信息解密 string encryptAlgorithm HttpContext.Current.Request.Form[encryptAlgorithm]; string encryptKey HttpContext.Current.Request.Form[encryptKey]; string encryptIv HttpContext.Current.Request.Form[encryptIv]; if (!string.IsNullOrEmpty(encryptAlgorithm)) { fileData DecryptFile(fileData, encryptAlgorithm, encryptKey, encryptIv); } // 保存解密后的数据 File.WriteAllBytes(filePath, fileData); // ...原有代码 }2023年5月21日 星期日 晴测试与调试今天进行了全面的测试浏览器兼容性Chrome/Firefox/Edge完美支持文件夹上传IE8降级为单文件上传Flash方案Safari基本功能正常文件夹支持有限大文件测试成功上传5GB和10GB文件分片上传和合并功能正常文件夹结构保留了原始文件夹层级数据库记录了完整的路径信息加密测试AES加密上传和解密下载正常SM4需要引入专门库暂未完全实现待解决问题IE8下的文件夹上传限制SM4加密的完整实现性能优化大文件夹上传时的内存使用断点续传的完善2023年5月22日 星期一 多云最终优化IE8优化添加了明确的提示告知IE8用户无法使用文件夹上传提供了批量上传的替代方案前端优化添加了上传速度显示改进了错误处理和重试机制注意您当前使用的是IE8浏览器不支持文件夹上传功能。请使用Chrome、Firefox等现代浏览器以获得完整功能。 速度: {{ uploadStats.speed }} 剩余时间: {{ uploadStats.timeLeft }}后端优化添加了事务支持确保数据库记录和文件存储的一致性改进了错误日志记录// 在SaveToDatabase方法中添加事务 using (SqlConnection conn new SqlConnection(connStr)) { conn.Open(); SqlTransaction transaction conn.BeginTransaction(); try { string sql INSERT INTO UploadedFiles (FileName, RelativePath, FilePath, ContentType, FileSize, UploadTime) VALUES (FileName, RelativePath, FilePath, ContentType, FileSize, UploadTime); SqlCommand cmd new SqlCommand(sql, conn, transaction); // ...参数设置 cmd.ExecuteNonQuery(); transaction.Commit(); } catch { transaction.Rollback(); throw; } }总结经过一周的努力系统基本实现了需求支持20GB大文件上传支持文件和文件夹上传保留层级结构兼容IE8到现代浏览器支持AES加密SM4需要额外库完整的数据库记录待完成工作完善SM4加密支持添加更详细的日志系统实现更完善的断点续传添加用户权限控制代码获取完整的代码我已经上传到GitHub示例链接实际使用时请替换https://github.com/example/large-file-uploader欢迎加入QQ群交流374992201注由于时间和精力限制部分功能如SM4加密尚未完全实现但提供了框架和思路。实际项目中需要根据具体需求进一步完善。设置框架安装.NET Framework 4.7.2https://dotnet.microsoft.com/en-us/download/dotnet-framework/net472框架选择4.7.2添加3rd引用编译项目NOSQLNOSQL无需任何配置可直接访问页面进行测试SQL使用IIS大文件上传测试推荐使用IIS以获取更高性能。使用IIS Express小文件上传测试可以使用IIS Express创建数据库配置数据库连接信息检查数据库配置访问页面进行测试相关参考文件保存位置效果预览文件上传文件刷新续传支持离线保存文件进度在关闭浏览器刷新浏览器后进行不丢失仍然能够继续上传文件夹上传支持上传文件夹并保留层级结构同样支持进度信息离线保存刷新页面关闭页面重启系统不丢失上传进度。下载完整示例下载完整示例
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

鼓楼做网站公司哪家好长沙企业网站建设团队

Linux平台Arduino开发环境搭建全攻略:从零配置到生产级稳定你是不是也经历过这样的时刻?满怀期待地把Arduino板插上Linux电脑,打开IDE准备上传第一个“Blink”程序,结果却弹出一连串错误:“Permission denied”、“Can…

张小明 2025/12/30 4:41:34 网站建设

肯尼亚网站域名东莞网站建设最优

深入探索Chef:架构、运行机制与关键概念解析 1. HTTP请求示例与Ruby基础 在进行HTTP请求时,不同的URL输入会产生不同的结果。例如,向 http://www.oreilly.com 发起GET请求成功,因为传递了有效的URL;而向 123 发起GET请求失败,因为URL无效。在代码中, HTTPRequest…

张小明 2025/12/30 4:33:44 网站建设

网站上线需要哪些步骤广州wap网站建设

题目描述动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形。A 吃 B,B 吃 C,C 吃 A。现有 N 个动物,以 1∼N 编号。每个动物都是 A,B,C 中的一种,但是我们并不知道它到底是哪一种。有人用两种说法对这 N…

张小明 2025/12/31 20:39:30 网站建设

做网站需要几万块吗WordPress中文king主题

Python安装配置GPT-SoVITS环境完整步骤详解 在内容创作、虚拟主播和个性化语音助手日益普及的今天,如何用极少量语音数据快速克隆出高度拟真的声音,已成为AI音频领域最引人关注的技术方向之一。传统语音合成系统往往需要数小时的专业录音与复杂的训练流程…

张小明 2025/12/30 10:23:07 网站建设

培训平台网站东莞网站制作的公司

摘要复杂光学光栅结构被广泛用于多种应用,如光谱仪、近眼显示系统等。利用傅里叶模态法(FMM,或称RCWA) VirtualLab Fusion 提供了一种用于任意光栅结构严格分析的简单方法。利用图形用户界面,用户可以设置堆栈的几何形状,从而产生…

张小明 2025/12/30 11:05:44 网站建设

网站建设栏目说明网站打不开404

Apache Doris Web UI可视化管理终极指南:告别命令行烦恼 【免费下载链接】doris Apache Doris is an easy-to-use, high performance and unified analytics database. 项目地址: https://gitcode.com/gh_mirrors/dori/doris 还在为繁琐的命令行操作而头疼吗…

张小明 2025/12/29 17:48:34 网站建设