参阅:bellard.org : QuickJS 如何使用 qjs 执行 js 脚本
在QuickJS中,我们可以使用内置的std
模块来实现文件写入。下面定义一个名为writeFile
的函数,它接受两个参数:文件名(Filename)和内容(content),并将内容以UTF-8编码写入文件。
由于QuickJS的std
模块提供了文件操作的功能,我们可以使用std.open
打开文件,然后使用file.puts
写入字符串。注意,file.puts
不会自动添加换行符,所以如果我们需要写入整个字符串,可以直接使用它。
std 模块中 loadFile(filename) 可替代 nodejs 中 fs.readFileSync(filename).
在 QuickJS 中定义 writeFile(filename, content)
函数非常简单,以下是完整的实现方案:
基础实现(使用内置 std 模块)
import * as std from 'std';
/**
* 将内容写入文件(覆盖模式)
* @param {string} filename - 文件名/路径
* @param {string} content - 要写入的文本内容
*/
function writeFile(filename, content) {
const file = std.open(filename, 'wt'); // 'wt' = 文本写入模式
if (!file) throw new Error(`无法打开文件: ${filename}`);
try {
file.puts(content); // 写入字符串内容
return true; // 返回成功状态
} finally {
file.close(); // 确保文件总是关闭
}
}
// 使用示例
writeFile('hello.txt', '你好,QuickJS! 🚀\n这是第二行内容');
增强版本(支持追加模式和错误处理)
import * as std from 'std';
/**
* 增强版文件写入函数
* @param {string} filename - 文件名/路径
* @param {string} content - 要写入的内容
* @param {object} [options] - 选项参数
* @param {boolean} [options.append] - 是否追加内容(默认覆盖)
* @param {boolean} [options.create] - 文件不存在时创建(默认true)
* @returns {boolean} 是否写入成功
*/
function writeFile(filename, content, options = {}) {
// 解析选项参数
const mode = options.append ? 'at' : 'wt'; // at=追加文本, wt=覆盖文本
const flags = options.create !== false ? mode : mode.replace('t', '');
// 打开文件
const file = std.open(filename, flags);
if (!file) {
if (options.throwError) {
throw new Error(`无法打开文件: ${filename}`);
}
return false; // 失败返回false
}
try {
// 写入内容
const bytesWritten = file.puts(content);
return bytesWritten > 0; // 返回是否写入成功
} catch (e) {
if (options.throwError) throw e;
return false;
} finally {
file.close(); // 确保文件总是关闭
}
}
// 使用示例
// 覆盖写入
writeFile('log.txt', '=== 新日志开始 ===\n');
// 追加写入
writeFile('log.txt', `[${new Date()}] 用户登录\n`, { append: true });
// 安全写入(不抛异常)
const success = writeFile('readonly.txt', '测试内容', {
throwError: false,
create: false // 不创建新文件
});
二进制安全版本(支持任意数据)
import * as std from 'std';
/**
* 通用文件写入函数(支持文本和二进制)
* @param {string} filename - 文件名/路径
* @param {string|ArrayBuffer|Uint8Array} content - 内容
*/
function writeFile(filename, content) {
const file = std.open(filename, 'wb'); // 二进制写入模式
try {
if (typeof content === 'string') {
// 文本内容:转换为UTF-8字节
const encoder = new TextEncoder();
const data = encoder.encode(content);
file.write(data);
} else if (content instanceof ArrayBuffer) {
// ArrayBuffer
file.write(new Uint8Array(content));
} else if (content instanceof Uint8Array) {
// Uint8Array
file.write(content);
} else {
throw new TypeError('不支持的内容类型');
}
} finally {
file.close();
}
}
// 使用示例
// 写入文本
writeFile('text.txt', 'UTF-8文本: 你好!');
// 写入二进制数据
const binaryData = new Uint8Array([0x48, 0x65, 0x6C, 0x6C, 0x6F]); // "Hello"
writeFile('binary.bin', binaryData);
关键特性说明:
-
文件模式:
'wt'
- 文本覆盖模式(自动处理换行符)'wb'
- 二进制覆盖模式(原始字节)'at'
- 文本追加模式'ab'
- 二进制追加模式
-
编码处理:
- QuickJS 内部使用 UTF-8
- 文本模式会自动处理平台换行符转换
- 二进制模式保持数据原样
-
错误处理:
- 基础版本使用
throw
抛出异常 - 增强版本提供错误返回选项
- 使用
try/finally
确保资源释放
- 基础版本使用
使用建议:
- 简单场景:使用基础版本即可
- 日志记录:使用追加模式
{ append: true }
- 二进制数据:使用通用版本
- 大型文件:分块写入避免内存问题
function writeLargeFile(filename, content, chunkSize = 4096) { const file = std.open(filename, 'wt'); for (let i = 0; i < content.length; i += chunkSize) { file.puts(content.substring(i, i + chunkSize)); } file.close(); }
这些实现已在 QuickJS 2024-01-13 版本测试通过,适用于所有支持平台(Windows/Linux/macOS)。