在节点中编辑大文件

时间:2017-05-30 15:01:17

标签: javascript node.js file nodes

我有一个大小未知的文件test.txt。与其他服务共享文件,我必须从此文件中读取以进行编辑。只是小编辑更改时间戳到现在。 在不读取整个文件的情况下编辑它的最佳方法是什么,然后重新编写。我不觉得这是一种正确的方法。我知道createReadStream和createWriteStream,但我不想复制文件和浪费资源,尤其是内存。 感谢。

3 个答案:

答案 0 :(得分:1)

我不知道如何在不至少打开文件的情况下阅读要更改的文件内容,更改需要更改的内容然后重新编写文件。 Node中最有效和最高效的方法是通过流,因为您不需要一次读取整个文件。假设您需要编辑的文件有新行或回车符,您可以使用Readline模块逐行迭代有问题的文件,并检查该行是否包含您想要更改的文本。然后,您可以将该数据写入旧文本所在的文件中。

如果您没有换行符,则可以选择使用Transform Stream并检查每个块的匹配文本,但这可能需要将多个块拼接在一起以识别要替换的文本。

我知道您不希望或多或少地根据所做的更改来复制文件,但我无法提出另一种效率相同的方法。 < / p>

const fs = require('fs')
const readline = require('readline')

const outputFile = fs.createWriteStream('./output-file.txt')
const rl = readline.createInterface({
    input: fs.createReadStream('./input-file.txt')
})

// Handle any error that occurs on the write stream
outputFile.on('err', err => {
    // handle error
    console.log(err)
})

// Once done writing, rename the output to be the input file name
outputFile.on('close', () => { 
    console.log('done writing')

    fs.rename('./output-file.txt', './input-file.txt', err => {
        if (err) {
          // handle error
          console.log(err)
        } else {
          console.log('renamed file')
        }
    }) 
})

// Read the file and replace any text that matches
rl.on('line', line => {
    let text = line
    // Do some evaluation to determine if the text matches 
    if (text.includes('replace this text')) {
        // Replace current line text with new text
        text = 'the text has been replaced'
    }
    // write text to the output file stream with new line character
    outputFile.write(`${text}\n`)
})

// Done reading the input, call end() on the write stream
rl.on('close', () => {
    outputFile.end()
})

答案 1 :(得分:0)

如果您只想更改时间戳,可以使用fs.futimes()。原生于版本v0.4.2的节点。

var fs = require("fs");

var fd = fs.openSync("file"); // Open a file descriptor

var now = Date.now() / 1000;
fs.futimesSync(fd, now, now); // Modify it by (fd, access_time, modify_time)

fs.closeSync(fd); // Close file descriptor

这样你就不依赖于任何npm包。

您可以在此处阅读更多内容:https://nodejs.org/api/fs.html#fs_fs_futimes_fd_atime_mtime_callback

答案 2 :(得分:0)

你需要像触摸linux命令行这样的东西,而npm package正是这样做的。