QuickJS 定义函数 writeFile(filename, content)

参阅: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);

关键特性说明:

  1. 文件模式

    • 'wt' - 文本覆盖模式(自动处理换行符)
    • 'wb' - 二进制覆盖模式(原始字节)
    • 'at' - 文本追加模式
    • 'ab' - 二进制追加模式
  2. 编码处理

    • QuickJS 内部使用 UTF-8
    • 文本模式会自动处理平台换行符转换
    • 二进制模式保持数据原样
  3. 错误处理

    • 基础版本使用 throw 抛出异常
    • 增强版本提供错误返回选项
    • 使用 try/finally 确保资源释放

使用建议:

  1. 简单场景:使用基础版本即可
  2. 日志记录:使用追加模式 { append: true }
  3. 二进制数据:使用通用版本
  4. 大型文件:分块写入避免内存问题
    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)。
wanghai

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值