JavaScript在浏览器和Node.js两种不同运行环境下,提供了不同的文件系统操作能力,对应不同的API和使用场景,开发者可以根据实际开发需求选择合适的实现方式。

浏览器环境下的文件操作
浏览器出于安全限制,不能直接访问用户本地文件系统,但是可以通过标准的File API实现用户主动选择的文件读取、拖放文件处理等操作,所有操作都需要用户主动触发,不能静默读取本地文件。
1. 通过文件输入框读取文件
最常见的场景是用户通过<input type="file">标签选择文件后,读取文件内容,核心使用FileReader对象实现,具体代码示例如下:
// 获取文件输入框元素
const fileInput = document.querySelector('#fileInput');
// 监听文件选择变化事件
fileInput.addEventListener('change', function(e) {
// 获取用户选择的文件列表
const files = e.target.files;
if (files.length === 0) {
return;
}
// 取第一个选中的文件
const file = files[0];
// 创建FileReader实例
const reader = new FileReader();
// 监听读取完成事件
reader.onload = function(event) {
// event.target.result就是文件的内容
console.log('文件内容:', event.target.result);
// 可以在这里把内容渲染到页面上
document.querySelector('#content').textContent = event.target.result;
};
// 监听读取错误事件
reader.onerror = function() {
console.error('文件读取失败');
};
// 以文本形式读取文件,也可以根据需求使用readAsDataURL、readAsArrayBuffer等
reader.readAsText(file, 'utf-8');
});2. 拖放文件读取
除了文件输入框,还可以监听页面的拖放事件,让用户把文件拖到页面中读取,代码示例如下:
// 获取拖放区域元素
const dropZone = document.querySelector('#dropZone');
// 阻止默认的拖放行为,避免出现浏览器默认打开文件的情况
dropZone.addEventListener('dragover', function(e) {
e.preventDefault();
});
dropZone.addEventListener('drop', function(e) {
e.preventDefault();
// 获取拖放的文件列表
const files = e.dataTransfer.files;
if (files.length === 0) {
return;
}
const file = files[0];
const reader = new FileReader();
reader.onload = function(event) {
console.log('拖放文件内容:', event.target.result);
};
reader.readAsText(file);
});3. 浏览器端写入文件
浏览器端如果要生成文件并让用户下载,不需要直接写入本地文件系统,可以通过Blob和URL.createObjectURL实现,代码示例如下:
// 要写入的内容
const content = '这是要保存到文件的内容';
// 创建Blob对象
const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
// 生成临时的下载链接
const url = URL.createObjectURL(blob);
// 创建a标签触发下载
const a = document.createElement('a');
a.href = url;
a.download = 'test.txt'; // 下载的文件名
a.click();
// 释放临时链接
URL.revokeObjectURL(url);Node.js环境下的文件操作
Node.js运行在服务端,没有浏览器的安全限制,可以通过内置的fs模块直接操作服务器的文件系统,支持文件的读写、目录的创建删除、文件状态查询等完整操作。
1. 同步和异步文件读取
fs模块提供了同步和异步两种文件读取方式,异步方式不会阻塞事件循环,更适合实际生产使用,代码示例如下:
const fs = require('fs');
// 异步读取文件,回调函数形式
fs.readFile('./test.txt', 'utf-8', function(err, data) {
if (err) {
console.error('读取文件失败:', err);
return;
}
console.log('异步读取的文件内容:', data);
});
// Promise形式读取,Node.js v10+支持
fs.promises.readFile('./test.txt', 'utf-8')
.then(data => {
console.log('Promise读取的文件内容:', data);
})
.catch(err => {
console.error('Promise读取文件失败:', err);
});
// 同步读取文件,会阻塞线程,仅适合初始化等场景
try {
const syncData = fs.readFileSync('./test.txt', 'utf-8');
console.log('同步读取的文件内容:', syncData);
} catch (err) {
console.error('同步读取文件失败:', err);
}2. 文件写入操作
文件写入同样支持同步和异步方式,也可以指定写入模式,比如追加写入,代码示例如下:
const fs = require('fs');
// 异步写入文件,默认是覆盖写入
fs.writeFile('./output.txt', '这是新写入的内容', 'utf-8', function(err) {
if (err) {
console.error('写入文件失败:', err);
return;
}
console.log('文件写入成功');
});
// 追加写入内容到文件末尾
fs.appendFile('./output.txt', '\n这是追加的内容', 'utf-8', function(err) {
if (err) {
console.error('追加写入失败:', err);
return;
}
console.log('追加写入成功');
});3. 目录操作
Node.js的fs模块也支持目录的创建、读取、删除等操作,代码示例如下:
const fs = require('fs');
const path = require('path');
// 创建目录,recursive为true支持创建多级目录
fs.mkdir('./newDir/subDir', { recursive: true }, function(err) {
if (err) {
console.error('创建目录失败:', err);
return;
}
console.log('目录创建成功');
});
// 读取目录下的所有文件和子目录
fs.readdir('./', function(err, files) {
if (err) {
console.error('读取目录失败:', err);
return;
}
console.log('目录下的内容:', files);
});
// 删除目录,recursive为true可以删除非空目录
fs.rm('./newDir', { recursive: true, force: true }, function(err) {
if (err) {
console.error('删除目录失败:', err);
return;
}
console.log('目录删除成功');
});不同场景的选择建议
如果是开发前端网页应用,需要操作用户的本地文件,只能使用浏览器提供的File API,且所有操作都需要用户主动触发,不能静默访问文件。如果是开发服务端应用、命令行工具等Node.js场景,需要使用fs模块,可以根据需求选择同步或异步API,异步API更推荐用于高并发场景,避免阻塞线程。
另外需要注意,浏览器端的文件操作都运行在用户的客户端,不会影响到服务器文件,而Node.js的文件操作是操作服务器本地的文件系统,需要注意权限控制,避免误操作删除重要文件。
JavaScript文件系统操作File_APINode.js_fs浏览器文件处理修改时间:2026-06-07 03:30:13