全部版块 我的主页
论坛 数据科学与人工智能 IT基础 JAVA语言开发
78 0
2025-11-24

文件管理系统毕业设计:从零开始的艰难历程

1. 毕业设计初遇难题

“这项目简直是要我命!”当我第一次看到导师布置的文件管理系统需求文档时,差点把手中的珍珠奶茶喷出来。 系统要求支持10G大文件上传、具备断点续传功能、兼容IE8浏览器,还要实现加密存储。这些条件放在一起,就像是让人用诺基亚手机去运行《王者荣耀》——根本不在一个时代! 而我的开发设备还是一台服役五年的联想小新,打开Chrome都卡得像在播放幻灯片。现在却要用它来搭建一个高性能的大文件处理系统?简直是挑战物理极限。

2. 技术选型的真实心路

2.1 前端框架的选择与落差

一开始我兴奋地选择了Vue3:“终于不用写jQuery那种远古代码了!”
当时心想,现代化的响应式语法加上丰富的组件生态,开发效率肯定飞升。
import { ref } from 'vue';
const fileList = ref([]);
const isUploading = ref(false);
const uploadProgress = ref(0);
但现实很快打了脸——IE8压根不支持ES6语法,更别提Vue3这种现代框架。刚搭好的前端结构,瞬间成了无法运行的废代码。
那一刻,心情直接跌入谷底。

2.2 断点续传的实现困境

起初我以为断点续传不过是把文件切分成多个块依次上传,逻辑清晰简单:
function resumeUpload(file) {
  const chunks = sliceFile(file);
  chunks.forEach(chunk => {
    if (!isUploaded(chunk)) {
      uploadChunk(chunk);
    }
  });
}
然而真正动手才发现问题重重:
  • IE8完全不支持File API,连读取文件都做不到
  • 对大文件进行切片时,浏览器频繁崩溃
  • 进度信息想存进LocalStorage?抱歉,IE8只支持userData机制
  • 处理10G级别的文件,内存直接耗尽,页面无响应
最终只能无奈写下:
try {
  throw new Error("我想退学");
} catch (e) {
  console.error(e.message);
}

2.3 文件夹上传的幻想破灭

需求中提到要保留原始目录层级结构,听起来就很复杂。 理想中的递归上传代码如下:
function uploadFolder(folder) {
  for (const entry of folder.entries()) {
    if (entry.isFile) {
      uploadFile(entry);
    } else {
      createRemoteFolder(entry.name);
      uploadFolder(entry);
    }
  }
}
可现实中:
  • IE8根本不提供选择整个文件夹的功能
  • 不同国产浏览器对文件API的支持差异极大
  • 连基本的文件夹选取都无法完成,何谈结构还原?
所谓的“保留层级”,最终变成了一句空话。

3. SpringBoot后端的崩溃记录

3.1 处理大文件上传的失败尝试

最开始写的Controller简洁明了:
@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) {
    file.transferTo(new File("/uploads/" + file.getOriginalFilename()));
    return "上传成功!";
}
结果一测试就炸了:
  • 10G文件直接导致JVM内存溢出
  • 请求超时成为常态
  • Tomcat 6.0即使设置了maxPostSize=10737418240,也因配置老旧而拒绝服务
看似简单的接口,在真实场景下几乎不可行。

3.2 分块上传服务端的现实挑战

为了应对大文件,改为分块上传:
@PostMapping("/chunk")
public String uploadChunk(
    @RequestParam("file") MultipartFile chunk,
    @RequestParam("chunkNumber") int chunkNumber,
    @RequestParam("totalChunks") int totalChunks) {
    
    saveChunk(chunk, chunkNumber);
    if (isUploadComplete(totalChunks)) {
        mergeChunks();
        return "上传完成";
    }
    return "分块已接收";
}
但实际运行暴露更多问题:
  • 合并大量分块时服务器IO负载飙升
  • 多用户并发上传引发数据库锁竞争
  • 若中途断电或宕机,已上传的数据难以恢复一致性
原本设想流畅的流程,在高负载下变得极其脆弱。

4. 加密方案的设计误区

最初我对加密的理解非常浅显:“加个密钥不就好了?”于是写下了这样的代码:
public void saveFileWithEncryption(MultipartFile file) throws Exception {
    String key = "mySuperSecretKey123"; // 固定密钥(严重安全隐患!)
后来才意识到,使用硬编码密钥是极不安全的做法,一旦泄露整个系统将毫无防护能力。而且在IE8环境下,Web Crypto API也无法使用,导致客户端加密几乎无法实现。 最终只能回归服务端加密,并采用临时密钥+动态生成的方式提升安全性,但仍受限于整体架构和技术栈的陈旧,安全性和性能之间始终难以平衡。
// 问题清单:
// 1. 大文件直接读入内存?存在内存溢出风险
// 2. 使用固定密钥?安全漏洞极大,安全人员已严阵以待
// 3. 加密性能堪忧?处理10G文件的时间足以让我毕业十次
// 4. 浏览器兼容性陷入混乱



6. 我的救赎之路  
在经历了多次系统崩溃与调试失败后,我逐步摸索出一套切实可行的优化方案:

6.1 前端优化策略  
采用 WebUploader 实现稳定上传机制,核心代码如下:  
const uploader = WebUploader.create({
    swf: 'path/to/Uploader.swf', // Flash 回退支持,保障 IE8 兼容
    server: '/api/upload',
    pick: '#filePicker',
    chunked: true,
    chunkSize: 2 * 1024 * 1024, // 每个分片大小设为 2MB
    threads: 3, // 支持三线程并发上传
    formData: {
        uid: 123 // 用于标识用户,支持断点续传功能
    }
});

// 将上传状态持久化存储至客户端数据库  
function saveUploadState(state) {
    // 省略具体兼容性判断逻辑
    if (window.indexedDB) {
        // 优先使用 IndexedDB 存储
    } else if (window.openDatabase) {
        // 兜底使用 WebSQL
    } else {
        // 最终降级至 cookie 或 localStorage(注意容量限制)
    }
}



5. 兼容性困境实录  
“必须支持 IE8 和国产浏览器?”——这要求令人窒息。  

以下是一段逐渐失效的浏览器检测逻辑:  
function checkBrowserCompatibility() {
    const isIE8 = /*@cc_on!@*/false || document.documentMode === 8;
    const isUOSBrowser = navigator.userAgent.includes('UOS');
    
    if (isIE8) {
        alert('建议您升级浏览器,或者换个电脑,甚至考虑换个专业...');
        return false;
    }
    
    if (isUOSBrowser) {
        alert('当前国产浏览器功能受限,强烈建议切换至 Chrome 浏览器');
        return false;
    }
    
    return true;
}  

实际测试结果:  
学校机房所有设备均触发首个警告弹窗,最终导致被老师约谈。



6.2 后端架构改进  
针对大文件场景,引入基于随机访问的分块处理机制:  

@PostMapping("/upload/chunk")
public ResponseEntity uploadChunk(
    @RequestParam("file") MultipartFile chunk,
    @RequestParam("chunkNumber") int chunkNumber,
    @RequestParam("totalChunks") int totalChunks,
    @RequestParam("identifier") String identifier) throws IOException {

    // 为每个上传任务创建独立临时目录
    Path tempDir = Paths.get("/tmp/uploads", identifier);
    if (!Files.exists(tempDir)) {
        Files.createDirectories(tempDir);
    }

    // 将接收到的分片写入对应临时文件
    Path chunkFile = tempDir.resolve(String.valueOf(chunkNumber));
    Files.copy(chunk.getInputStream(), chunkFile, StandardCopyOption.REPLACE_EXISTING);

    // 判断所有分片是否均已接收完毕
    if (isUploadComplete(tempDir, totalChunks)) {
        mergeFiles(tempDir, identifier); // 合并文件
        return ResponseEntity.ok("上传完成");
    }

    return ResponseEntity.ok("分块已成功接收");
}

7. 给后来开发者的经验总结  
- 不要执着于完全兼容 IE8  
  推荐做法:直接弹窗提示用户升级现代浏览器即可  

- 分块尺寸需权衡网络与磁盘性能  
  建议设置在 2MB 左右,兼顾效率与稳定性  

- 优先选用成熟开源库  
  避免重复造轮子,选择如 WebUploader 等经过验证的解决方案,显著降低维护成本

在开发过程中,采用合理的架构和技术手段能够有效提升项目的稳定性和可维护性。例如,WebUploader 已经为开发者解决了大量浏览器兼容性问题,使得前端文件上传功能更加可靠。

后端方面,推荐使用流式处理技术来操作数据,这样可以避免因一次性加载过多数据而导致的内存溢出问题。通过分块读取和处理,系统资源得以更高效地利用。

数据库配置与初始化

首先需要创建相应的数据库,确保存储结构满足业务需求。

完成数据库创建后,进行连接配置,保证应用能正确访问数据源。

Maven 项目在构建时会自动下载所需的依赖包,简化了环境搭建流程,提升了开发效率。

项目启动与运行验证

执行启动命令后,若控制台输出正常日志信息,则表示服务已成功运行。

接口访问与功能测试

系统默认提供了基础页面接口,可用于初步验证服务是否可用。

通过浏览器访问指定地址,即可查看前端交互界面并进行基本操作测试。

检查数据库中对应的数据表内容,确认上传或写入操作是否生效。

核心功能演示

文件上传功能:支持常规文件上传,具备良好的用户反馈机制。

断点续传(刷新/关闭浏览器后继续):上传进度可在本地持久化保存,即使关闭或刷新浏览器,仍能恢复上传任务,避免重复传输。

文件夹上传:不仅支持整个文件夹的上传,还能保留原有的目录层级结构。上传进度同样实现离线存储,即便页面关闭、刷新甚至系统重启,进度也不会丢失。

示例代码获取

提供完整示例工程下载,便于开发者快速上手和学习集成方式。

测试策略建议从小规模开始,尽早介入。不要等到所有代码编写完毕才开始测试,那样容易积累大量难以排查的问题。

关于求职方向,不妨先专注于顺利完成毕业设计。至于某些群聊中宣传的“月入十万”机会……请保持清醒:

“如果一个群要求你交费、拉人头,并承诺高额回报,请立刻退出!这种风险远比调试 IE8 的兼容性问题严重得多。”

接下来,我得继续攻克我的文件管理系统了,祝我顺利吧!如果你也在做类似的项目,欢迎交流经验。

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群