使用nodejs从文件中删除最后n行
我试图从文件中删除最后3行使用fs作为nodejs的一部分。 我目前正在读取文件到内存中,然后再次写入没有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); }); });
我们来创build一个巨大的文件:
$ 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
,它不读取整个文件,它寻find最后,然后读取块,直到达到预期的行数,然后它显示在正确的方向,直到文件的结尾的行。 现在我现在要消失的字节数。 然后我使用fs.stat
,它告诉我文件中的总字节数。 现在,我知道在最后的n
行删除后,我在文件中实际需要多less字节。 最后,我使用fs.truncate
,这会导致常规文件被截断为指定的大小(以字节为单位)。
更新:
OP说这个平台是Windows。 在这种情况下,我们可以修改这个程序来不调用另一个实用程序,而是在节点本身做所有事情。 幸运的是,所需的function已经作为节点模块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