使用nodejs从文件中删除最后n行

2023-11-29

我正在尝试使用 fs 作为 nodejs 的一部分从文件中删除最后 3 行。我目前正在将文件读入内存,然后在没有这 3 行的情况下再次写入它,但我确信有一种更有效的方法,不需要将整个文件读入内存。

我现在的代码

fs.readFile(filename, function (err, data) {
    if (err) throw err;
    theFile = data.toString().split("\n");
    theFile.splice(-3, 3);
    fs.writeFile(filename, theFile.join("\n"), function (err) {
        if (err) {
            return console.log(err);
        }
        console.log("Removed last 3 lines");
        console.log(theFile.length);

    });
});

让我们创建一个巨大的文件:

$ base64 /dev/urandom | head -1000000 > /tmp/crap
$ wc -l /tmp/crap
1000000 /tmp/crap
$ du -sh /tmp/crap
74M /tmp/crap

这是你的代码:

$ cat /tmp/a.js
var fs = require('fs');

var filename = '/tmp/crap1';

fs.readFile(filename, function(err, data) {
    if(err) throw err;
    theFile = data.toString().split("\n");
    theFile.splice(-3,3);
    fs.writeFile(filename, theFile.join("\n"), function(err) {
    if(err) {
        return console.log(err);
    }
    console.log("Removed last 3 lines");
    console.log(theFile.length);
    });
});

这是我的:

$ cat /tmp/b.js
var fs = require('fs'),
    util = require('util'),
    cp = require('child_process');

var filename = '/tmp/crap2';
var lines2nuke = 3;
var command = util.format('tail -n %d %s', lines2nuke, filename);

cp.exec(command, (err, stdout, stderr) => {
    if (err) throw err;
    var to_vanquish = stdout.length;
    fs.stat(filename, (err, stats) => {
        if (err) throw err;
        fs.truncate(filename, stats.size - to_vanquish, (err) => {
            if (err) throw err;
            console.log('File truncated!');
        })
    });
});

让我们复制同一文件:

$ cp /tmp/crap /tmp/crap1
$ cp /tmp/crap /tmp/crap2

让我们看看谁更快:

$ time node a.js
Removed last 3 lines
999998
node a.js  0.53s user 0.19s system 99% cpu 0.720 total

$ time node b.js
File truncated!
node b.js  0.08s user 0.01s system 100% cpu 0.091 total

当我将文件大小增加 10 倍时,我的系统 a.js 内存不足;但对于 b.js,需要:

$ time node b.js
File truncated!
node b.js  0.07s user 0.03s system 6% cpu 1.542 total

我的代码使用tail,它不会读取整个文件,它会查找到末尾,然后向后读取块,直到达到预期的行数,然后以正确的方向显示行,直到文件末尾。现在我现在的字节数消失了。然后我用fs.stat,它告诉我文件中的总字节数。现在,我知道在删除最后的文件后,我实际上想要在文件末尾有多少字节n线。最后,我用fs.truncate,这会导致常规文件被截断为与其指定的大小(以字节为单位)完全相同的大小。

Update:

OP说平台是Windows。在这种情况下,我们可以将这个程序修改为not调用另一个实用程序,但在节点本身中执行所有操作。幸运的是,所需的功能已经作为节点模块提供给我们了read-last-lines。现在,更新后的与操作系统无关的代码如下所示:

$ npm install read-last-lines
$ cat /tmp/c.js 
var fs = require('fs'),
    rll = require('read-last-lines');

var filename = '/tmp/crap2';
var lines2nuke = 3;

rll.read(filename, lines2nuke).then((lines) => {
    var to_vanquish = lines.length;
    fs.stat(filename, (err, stats) => {
        if (err) throw err;
        fs.truncate(filename, stats.size - to_vanquish, (err) => {
            if (err) throw err;
            console.log('File truncated!');
        })
    });
});

对于 10 倍大小的文件,需要:

$ time node c.js
File truncated!
node c.js  0.14s user 0.04s system 8% cpu 2.022 total
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用nodejs从文件中删除最后n行 的相关文章

随机推荐

  • iOS 6.0 MPMoviePlayerController 全屏模式黑色?然后应用程序不再阻止任何操作

    当屏幕为黑色时 MPMoviePlayerController 视频将进入全屏模式 然后该应用程序就被屏蔽了 此问题仅适用于 iOS 6 0 但 iOS 5 1 运行良好 这是我的代码 如果我双击播放器全屏打开 但显示黑屏 self mov
  • PHP 数组语法:array(...) 或 [...] [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 在 PHP 中 这些相同吗 x 1 2 3 and x array 1 2 3 这两种创建数组的方法是否存在不同的情况 有什么理由使用其中一种而不是另一种吗 它们与警告相同 x 1 2 3
  • 在 Access 中从另一个表的数据创建一个表

    这个问题是关于 MS Access 的 我想做的是 我在 Access 中有一个表 并且想使用第一个表中的数据创建另一个表 希望通过一些 VBA 代码自动创建 有关于如何执行此操作的任何建议吗 我对 VBA 和 Access 很陌生 因此任
  • Web API:具有不同 HTTP 动词的相同方法

    在 WEB API 控制器中 我们可以使用相同的方法名称和不同的 HTTP 动词吗 HttpGet public string Test return Success Get HttpPost public string Test int
  • 正则表达式多个条件

    我有一个包含 URL 的字符串 例如https xxxx yyyy com en 我怎样才能制作一个正则表达式来验证这一点both这些条件都满足吗 网址不包含xxxx The URL does包含任一 en or en 您可以使用 xxxx
  • 重定向选择框中的选择选项

    目前我正在使用这个
  • 合并具有大写和非大写版本的变量名称的列,而不指定变量名称

    我有一个 大 数据框 如下所示 library data table DT lt fread ID country year A b B a 4 NLD 2002 NA 1 NA 0 5 NLD 2002 NA 0 NA 1 6 NLD 2
  • 接近恒定时间旋转,不违反标准

    我花了很长时间试图想出一个不违反 C C 标准的恒定时间旋转 问题是边缘 角落情况 其中操作在算法中调用并且这些算法无法更改 例如 以下内容来自Crypto 并执行下面的测试工具海湾合作委员会乌桑 i e g fsanitize undef
  • 如何使用 Java prefuse 库创建条形图?

    我目前有prefuse绘制散点图 其中 X 轴是计算机名称 Y 轴是其温度 如何让它绘制显示值而不是离散点的条形 我目前正在使用以下代码来呈现点 ShapeAction shape new ShapeAction group Constan
  • 如何过滤大于x的数组值

    我一直在互联网上查找 但找不到任何介绍如何解决此问题的帖子 尽管我确信这是一个非常简单的修复 基本上我有一个包含数字值的数组 我想过滤掉任何大于 10 的数字并将它们添加到另一个数组中 这是到目前为止我所得到的 但我得到的是第一个数组中的所
  • 如何从 QUnit 测试触发本机 Javascript 事件?

    我正在开发一个不依赖于 jQuery 的 Javascript 库 尽管我的测试中可以使用 jQuery 和 QUnit 在库中 我按照 jQuery 的方式将事件附加到元素 if document addEventListener tab
  • 如何使用水豚has_text

    所以现在我已经让黄瓜 水豚 硒点击谷歌应用程序脚本 这很棒 但由于某种原因 我似乎无法按照我期望的方式检查页面正文中的文本 在调试器中 我可以抓取页面对象 我可以在浏览器中获得预期的文本 直接扫描html显示文本出现了两次 但是page h
  • 如何通过调整缓冲区大小来优化读写?

    如何优化标准 C C 11 中 std ifstream 和 std ofstream 的读写速度 无 POSIX 函数 1 我不太清楚缓冲区的作用 所以你能确认一下吗 用于读取 文件的很大一部分被预加载到内存中 因此缓冲区大小定义了这大部
  • Haskell:let 语句,将数据类型复制到自身(带/不带修改)不起作用

    我想通过更改一个字段来更新记录语法 所以我做了类似的事情 let rec rec field 1 但我发现我无法打印rec不再 意味着当我尝试时编译器似乎进入无限循环 所以我尝试这样做 let a 1 prints OK let a a n
  • UITextView - 禁用垂直滚动

    如何禁用 UITextView 中的垂直滚动 我希望它基本上只是水平滚动 在某些情况下 当试图限制不需要的 UITextView 滚动时 我发现向 UITextView 委托添加类似以下内容很有帮助 这是一个 UIScrollView 委托
  • 在 Powershell 中更新 VSTS WorkItem 的正确 Invoke-RestMethod 语法是什么 - 构造包含 Windows 路径的 JSON 字符串 [重复]

    这个问题在这里已经有答案了 当尝试使用 Invoke RestMethod 更新现有 VSTS 工作项时 我不断收到 您必须在请求正文中传递有效的补丁文档 这是我要传递的内容 Body op test path rev value 1 op
  • 使用 PHP 读取 MIME 数据

    我有一个第三方程序 它基本上允许用户发送电子邮件 然后将其显示在系统中 但问题是它生成这样的输出 我只想获取这些数据并将其格式化为合适的格式 我想避免正则表达式 是否有任何选项或标准方法可以以更美观的方式显示以下内容 基本上我会将下面的所有
  • 细胞景观。从 URL 加载依赖项

    这是一个非常简单的问题 如何通过 url 将 cytoscape 指示为来源 我知道与D3这很简单 cytoscape 的等效地址是什么 Thanks 您要查找的术语是 CDN 托管的代码副本 严格来说 即使您指定了本地副本 您仍然在使用
  • 在android中制作一个超链接textview

    我想为文本视图文本创建一个链接 例如Google 有没有办法建立这样的链接 即 当点击 Google 一词时 它应该打开相应的链接 欢迎任何想法 试试这个 让我知道会发生什么 使用java代码 TextView textView TextV
  • 使用nodejs从文件中删除最后n行

    我正在尝试使用 fs 作为 nodejs 的一部分从文件中删除最后 3 行 我目前正在将文件读入内存 然后在没有这 3 行的情况下再次写入它 但我确信有一种更有效的方法 不需要将整个文件读入内存 我现在的代码 fs readFile fil