Node.js如何删除文件中的第一行
我正在制作simple Node.js应用程序,我需要删除文件中的第一行。请问怎么做?我认为使用fs.write是可能的,但如何实现呢?这里是从文件中删除第一行的流式版本。Node.js如何删除文件中的第一行,node.js,file,line,Node.js,File,Line,我正在制作simple Node.js应用程序,我需要删除文件中的第一行。请问怎么做?我认为使用fs.write是可能的,但如何实现呢?这里是从文件中删除第一行的流式版本。 由于它使用流,这意味着您不需要在内存中加载整个文件,因此它更高效、更快速,并且可以处理非常大的文件,而无需在硬件上填充内存 var Transform = require('stream').Transform; var util = require('util'); // Transform sctreamer to
由于它使用流,这意味着您不需要在内存中加载整个文件,因此它更高效、更快速,并且可以处理非常大的文件,而无需在硬件上填充内存
var Transform = require('stream').Transform;
var util = require('util');
// Transform sctreamer to remove first line
function RemoveFirstLine(args) {
if (! (this instanceof RemoveFirstLine)) {
return new RemoveFirstLine(args);
}
Transform.call(this, args);
this._buff = '';
this._removed = false;
}
util.inherits(RemoveFirstLine, Transform);
RemoveFirstLine.prototype._transform = function(chunk, encoding, done) {
if (this._removed) { // if already removed
this.push(chunk); // just push through buffer
} else {
// collect string into buffer
this._buff += chunk.toString();
// check if string has newline symbol
if (this._buff.indexOf('\n') !== -1) {
// push to stream skipping first line
this.push(this._buff.slice(this._buff.indexOf('\n') + 2));
// clear string buffer
this._buff = null;
// mark as removed
this._removed = true;
}
}
done();
};
并像这样使用它:
var fs = require('fs');
var input = fs.createReadStream('test.txt'); // read file
var output = fs.createWriteStream('test_.txt'); // write file
input // take input
.pipe(RemoveFirstLine()) // pipe through line remover
.pipe(output); // save to file
另一种方式,不推荐。如果您的文件不大,并且您不介意将它们加载到内存中,则可以加载文件、删除行、保存文件,但这样做速度较慢,并且在大文件上无法正常工作
var fs = require('fs');
var filePath = './test.txt'; // path to file
fs.readFile(filePath, function(err, data) { // read file to memory
if (!err) {
data = data.toString(); // stringify buffer
var position = data.toString().indexOf('\n'); // find position of new line element
if (position != -1) { // if new line element found
data = data.substr(position + 1); // subtract string based on first line length
fs.writeFile(filePath, data, function(err) { // write file
if (err) { // if error, report
console.log (err);
}
});
} else {
console.log('no lines found');
}
} else {
console.log(err);
}
});
感谢@Lilleman的评论,我对原来的解决方案做了一个修改,它需要一个第三方模块“逐行”并可以防止内存溢出和在处理非常大的文件时出现争用情况
const fs = require('fs');
const LineReader = require('line-by-line');
const removeLines = function(srcPath, destPath, count, cb) {
if(count <= 0) {
return cb();
}
var reader = new LineReader(srcPath);
var output = fs.createWriteStream(destPath);
var linesRemoved = 0;
var isFirstLine = true;
reader.on('line', (line) => {
if(linesRemoved < count) {
linesRemoved++;
return;
}
reader.pause();
var newLine;
if(isFirstLine) {
newLine = line;
isFirstLine = false;
} else {
newLine = '\n' + line;
}
output.write(newLine, () => {
reader.resume();
});
})
.on('error', (err) => {
reader.pause();
return cb(err);
})
.on('close', () => {
return cb();
})
}
通过将“firstRemoved”更改为计数器,可以轻松修改它以删除一定数量的行:
var linesRemoved = 0;
...
if(linesRemoved < LINES_TO_BE_REMOVED) {
linesRemoved++;
return;
}
...
var linesRemoved=0;
...
如果(线条移动<线条移动){
linesRemoved++;
返回;
}
...
这里是另一种方式:
const fs = require('fs');
const filePath = './table.csv';
let csvContent = fs.readFileSync(filePath).toString().split('\n'); // read file and convert to array by line break
csvContent.shift(); // remove the the first element from array
csvContent = csvContent.join('\n'); // convert array back to string
fs.writeFileSync(filePath, csvContent);
非常感谢。我可以问一下,我为什么要看文件?我认为在不知道文件内容的情况下使用fs.write()删除它是可行的。用“”替换第一行怎么样?有可能吗。例如,在PHP中,很容易删除PHP中的线性摘要,这会带来成本。您需要编辑文件-这意味着它必须在硬盘上修改。要做到这一点,或者从技术上讲,您需要“过滤”缓冲区,然后使用流写入其余缓冲区(在第一行之后),或者加载文件>删除行>保存文件。您可以根据需要将任何内容附加到字符串中。请阅读如何使用JavaScript的一般教程,因为我可以清楚地看到在node和JS的一般领域缺乏知识<代码>数据='您的文本'+数据.substr(位置)代码>-将附加一些其他文本,而不是第一行。StackOverflow-不支持编码,它支持挑战。此外,请阅读以下内容:并在网站内使用评级系统,以便将答案标记为有效答案,或者如果答案具有误导性,则使用“向下”箭头标记答案。提供了从文件中删除第一行的流式版本,提供处理超大文件的能力。我根据这个答案创建了一个简单的库。它允许您删除X行数。你所要做的就是将数量传递给函数,然后关闭它。它被称为条带线,并且处于打开状态。请注意,output.write()在写入完成时确实有一个回调。如果磁盘的写入速度比读取速度慢,那么写入操作将排队,如果重写一个非常大的文件,应用程序最终将崩溃。这也创造了一个竞赛条件;当运行done()时,根本不能确定写入的文件是否包含所有行。@Lilleman感谢您的评论,我已对原始解决方案进行了修改。第一个非难看的解决方案。谢谢
const fs = require('fs');
const filePath = './table.csv';
let csvContent = fs.readFileSync(filePath).toString().split('\n'); // read file and convert to array by line break
csvContent.shift(); // remove the the first element from array
csvContent = csvContent.join('\n'); // convert array back to string
fs.writeFileSync(filePath, csvContent);