javascript怎么读取本地文件大小

javascript怎么读取本地文件大小

使用 ` 选取文件后,通过 event.target.files[0].size` 可获取文件大小(字节),需配合...

优惠价格:¥ 0.00
当前位置:首页 > 后端开发 > javascript怎么读取本地文件大小
详情介绍
使用 ` 选取文件后,通过 event.target.files[0].size` 可获取文件大小(字节),需配合

在Web开发中,由于浏览器的安全机制(同源策略),纯前端JavaScript无法直接遍历或任意读取用户设备的本地文件系统中的文件,这是为了防止反面网站未经授权访问用户的敏感数据,当用户主动通过 <input type="file"> 元素选择一个或多个文件后,JavaScript 可以通过 File API 获取所选文件的信息,包括其大小,以下是完整的实现原理、步骤、代码示例及注意事项。


核心原理与流程

  1. 用户触发:页面提供一个文件选择控件(如 <input type="file">)。
  2. 用户授权:用户点击该控件并选择一个或多个本地文件。
  3. JS获取文件对象:通过 input 元素的 files 属性获取到 FileList 对象。
  4. 读取文件信息:从 FileList 中取出具体的 File 对象,其 size 属性即为文件大小(单位:字节)。

关键限制:此方法仅能获取用户主动选择的文件信息,无法批量扫描或读取用户未主动选择的文件。


️ 实现步骤与代码详解

HTML结构

创建一个文件输入框和一个用于显示结果的区域:

<!-文件选择控件 -->
<input type="file" id="fileSelector" multiple>
<!-显示文件信息的容器 -->
<div id="fileInfo"></div>
  • 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 是非标准属性,仅部分浏览器支持,且依赖用户是否启用了相关权限。


️ 重要注意事项

  1. 安全性限制
    • 不能读取用户未主动选择的文件。
    • 不能获取文件的完整路径(仅部分浏览器提供相对路径)。
    • 不能直接修改文件内容(需配合后端上传/下载)。
  2. 性能优化
    • 大文件(>1GB)可能导致内存占用过高,建议结合 Web Worker 分片处理。
    • 如果只需验证文件大小是否符合要求,可在客户端提前拦截,减少不必要的上传。
  3. 跨浏览器兼容
    • File API 在现代浏览器(Chrome/Firefox/Safari/Edge)中均支持。
    • IE10+ 也支持,但旧版IE需 polyfill。
  4. 错误处理
    • 如果用户取消文件选择,files 会是空列表。
    • 可通过 try...catch 捕获潜在的异常(如内存不足)。

典型应用场景

  1. 上传前校验:限制用户只能上传小于5MB的图片。
    const maxSize = 5  1024  1024; // 5MB
    if (file.size > maxSize) {
        alert('文件过大,最大支持5MB');
        return false; // 阻止表单提交
    }
  2. 进度提示:显示已选文件的总大小。
    const totalSize = Array.from(files).reduce((sum, file) => sum + file.size, 0);
    console.log(`总大小: ${formatFileSize(totalSize)}`);
  3. 日志记录:调试时输出用户上传的文件信息。
    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 不支持直接获取文件夹大小,但可以通过以下变通方案实现:

  1. 引导用户将文件夹压缩成 ZIP 文件,然后上传并读取 ZIP 文件的大小。
  2. 使用第三方库(如 react-dropzone)实现递归上传文件夹内的所有文件,然后累加每个文件的大小。
  3. 如果项目允许使用电子应用框架(如 Electron),可以通过 Node.js 的 fs 模块直接读取文件夹大小。

通过 <input type="file"> + File API 的组合,可以安全地获取用户主动选择的文件大小,虽然存在一定限制,但已能满足大多数前端场景的需求(如上传前校验、信息展示),对于更复杂的文件操作(如目录遍历、文件内容修改),必须依赖后端服务或特定

0