【问题标题】:Edit large file in node在节点中编辑大文件
【发布时间】:2017-10-31 03:13:10
【问题描述】:

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

【问题讨论】:

  • 未测试,快速搜索:stackoverflow.com/questions/14177087/…
  • @dward — 该问题的公认答案正是该问题试图避免的问题
  • 使用流不会浪费很多内存。
  • @SLaks 使用流是关于从文件读取并写入另一个文件。好吧,它可以是我的选择之一。但这是我们在这里进行小编辑的唯一选择吗?

标签: javascript node.js file nodes


【解决方案1】:

如果您只想更改时间戳,可以使用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

【讨论】:

  • 是的,谢谢,但这里的时间戳是隐喻,我这里的真实情况是一个字符串将被更改为另一个随机字符串。
  • @JimmyJanson 所以你想改变文件的内容,对吧?我以为只是想更改文件时间戳。
  • 是的,我认为放置时间戳的内容可以让问题更容易理解。
【解决方案2】:

您需要类似 touch linux 命令行的东西,而 npm package 正是这样做的。

【讨论】:

    【解决方案3】:

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

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

    我知道您不想或多或少地复制带有更改的文件,但我想不出另一种同样有效的方法。

    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()
    })
    

    【讨论】:

    • 嗯,结果与您的建议相似,找不到更好的东西。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-04
    • 2021-12-26
    • 1970-01-01
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    • 2012-07-14
    相关资源
    最近更新 更多