javascript怎么读取本地文件大小
- 后端开发
- 2025-08-14
- 7
在Web开发中,由于浏览器的安全机制(同源策略),纯前端JavaScript无法直接遍历或任意读取用户设备的本地文件系统中的文件,这是为了防止恶意网站未经授权访问用户的敏感数据,当用户主动通过 <input type="file"> 元素选择一个或多个文件后,JavaScript 可以通过 File API 获取所选文件的信息,包括其大小,以下是完整的实现原理、步骤、代码示例及注意事项。
核心原理与流程
- 用户触发:页面提供一个文件选择控件(如 <input type="file">)。
- 用户授权:用户点击该控件并选择一个或多个本地文件。
- JS获取文件对象:通过 input 元素的 files 属性获取到 FileList 对象。
- 读取文件信息:从 FileList 中取出具体的 File 对象,其 size 属性即为文件大小(单位:字节)。
关键限制:此方法仅能获取用户主动选择的文件信息,无法批量扫描或读取用户未主动选择的文件。
️ 实现步骤与代码详解
HTML结构
创建一个文件输入框和一个用于显示结果的区域:

- multiple 属性允许用户一次选择多个文件。
- 后续可通过CSS美化界面,提升用户体验。
JavaScript逻辑
监听文件输入的变化事件,处理选中的文件:

document.getElementById('fileSelector').addEventListener('change', function(e) { const files = e.target.files; // FileList对象,类数组 const fileInfoDiv = document.getElementById('fileInfo'); fileInfoDiv.innerHTML = ''; // 清空上次的结果 if (files.length === 0) { fileInfoDiv.textContent = '未选择任何文件'; return; } // 遍历所有选中的文件 Array.from(files).forEach((file, index) => { // 创建显示单条文件信息的卡片 const card = document.createElement('div'); card.style.margin = '10px 0'; card.style.padding = '15px'; card.style.border = '1px solid #ccc'; card.style.borderRadius = '5px'; // 文件基本信息 const name = document.createElement('p'); name.textContent = `文件名: ${file.name}`; card.appendChild(name); const sizeInBytes = document.createElement('p'); sizeInBytes.textContent = `原始大小(B): ${file.size}`; card.appendChild(sizeInBytes); // 转换为常见单位(KB/MB/GB) const readableSize = formatFileSize(file.size); const readableSizeElem = document.createElement('p'); readableSizeElem.textContent = `可读大小: ${readableSize}`; card.appendChild(readableSizeElem); // 文件类型判断 const type = document.createElement('p'); type.textContent = `MIME类型: ${file.type || '未知'}`; card.appendChild(type); fileInfoDiv.appendChild(card); }); }); // 辅助函数:将字节转换为易读格式(KB/MB/GB) function formatFileSize(bytes) { if (bytes === 0) return '0 B'; const k = 1024; // 1KB=1024B const sizes = ['B', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; }
代码逐行解析
| 代码片段 | 作用 | 说明 |
|---|---|---|
| e.target.files | 获取用户选择的文件列表 | 返回一个 FileList 对象,类似数组,包含所有选中的文件 |
| file.size | 获取文件大小(字节) | 这是最直接的原始数据,适用于精确计算 |
| formatFileSize() | 格式化文件大小 | 将字节转换为更易读的 KB/MB/GB,提高可读性 |
| file.type | 获取文件MIME类型 | image/png, application/pdf,可用于初步校验文件类型 |
| Array.from(files) | 将 FileList 转为真数组 | 方便使用数组方法(如 forEach, map)进行遍历 |
File对象常用属性对照表
| 属性 | 描述 | 示例值 |
|---|---|---|
| name | 文件名(含扩展名) | example.jpg |
| size | 文件大小(字节) | 123456 |
| type | MIME类型 | image/jpeg |
| lastModified | 最后修改时间戳 | 1678901234567 |
| webkitRelativePath | 文件相对路径(仅Chrome/Edge) | Documents/photo.jpg |
️ 注意:webkitRelativePath 是非标准属性,仅部分浏览器支持,且依赖用户是否启用了相关权限。
️ 重要注意事项
- 安全性限制:
- 不能读取用户未主动选择的文件。
- 不能获取文件的完整路径(仅部分浏览器提供相对路径)。
- 不能直接修改文件内容(需配合后端上传/下载)。
- 性能优化:
- 大文件(>1GB)可能导致内存占用过高,建议结合 Web Worker 分片处理。
- 如果只需验证文件大小是否符合要求,可在客户端提前拦截,减少不必要的上传。
- 跨浏览器兼容:
- File API 在现代浏览器(Chrome/Firefox/Safari/Edge)中均支持。
- IE10+ 也支持,但旧版IE需 polyfill。
- 错误处理:
- 如果用户取消文件选择,files 会是空列表。
- 可通过 try...catch 捕获潜在的异常(如内存不足)。
典型应用场景
- 上传前校验:限制用户只能上传小于5MB的图片。 const maxSize = 5 1024 1024; // 5MB if (file.size > maxSize) { alert('文件过大,最大支持5MB'); return false; // 阻止表单提交 }
- 进度提示:显示已选文件的总大小。 const totalSize = Array.from(files).reduce((sum, file) => sum + file.size, 0); console.log(`总大小: ${formatFileSize(totalSize)}`);
- 日志记录:调试时输出用户上传的文件信息。 console.table(Array.from(files).map(file => ({ name: file.name, size: file.size, type: file.type })));
相关问答FAQs
Q1: 为什么直接调用 fs.readFileSync() 会报错?
A: 因为 fs 模块属于 Node.js 环境,而浏览器端的 JavaScript 运行在沙盒环境中,没有权限直接访问文件系统,浏览器中的 File API 只能在用户主动选择文件后获取其元数据,无法像 Node.js 那样自由读写文件,如果需要在网页中实现类似功能,必须通过用户交互(如拖拽或点击选择文件)触发。
Q2: 如何获取文件夹的大小而不是单个文件?
A: 目前浏览器的 File API 不支持直接获取文件夹大小,但可以通过以下变通方案实现:
- 引导用户将文件夹压缩成 ZIP 文件,然后上传并读取 ZIP 文件的大小。
- 使用第三方库(如 react-dropzone)实现递归上传文件夹内的所有文件,然后累加每个文件的大小。
- 如果项目允许使用电子应用框架(如 Electron),可以通过 Node.js 的 fs 模块直接读取文件夹大小。
通过 <input type="file"> + File API 的组合,可以安全地获取用户主动选择的文件大小,虽然存在一定限制,但已能满足大多数前端场景的需求(如上传前校验、信息展示),对于更复杂的文件操作(如目录遍历、文件内容修改),必须依赖后端服务或特定
