2013-06-28 3 views

ответ

12

Здесь представлена ​​потоковая версия удаления первой строки из файла.
Поскольку он использует потоки, означает, что вам не нужно загружать весь файл в память, поэтому он более эффективен и быстр, а также может работать с очень большими файлами без заполнения памяти на вашем оборудовании.

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); 
    } 
}); 
+0

большое спасибо. Могу я просто спросить, зачем мне читать файл? Я думаю, что его можно удалить с помощью fs.write() без знания содержимого файла. Как насчет замены первой строки на ""? Является ли это возможным. Например, в PHP, так легко удалить строку – user2316602

+0

Абстракции в PHP имеют затраты. Вам нужно отредактировать файл - это значит, что его нужно модифицировать на HDD. Для этого или технически вам нужно «отфильтровать» буфер, а затем записать остальные (после первой строки), с потоком или загрузить файл> удалить строку> сохранить файл. Вы можете добавить что угодно в свою строку, как хотите. Прочтите общие руководства по работе с JavaScript, так как я отчетливо вижу отсутствие знаний в общей области узла и JS. 'data = 'ваш текст' + data.substr (position);' - добавит другой текст вместо первой строки. StackOverflow - это не поддержка кодирования, это поддержка проблем. – moka

+0

Кроме того, ознакомьтесь с этим: http://stackoverflow.com/about и используйте рейтинговую систему на веб-сайте, чтобы отметить ответы как действительные или пометить их стрелкой «вниз», если они вводят в заблуждение. – moka

1

Вдохновленный другой ответ, вот исправленная версия потока:

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

const removeFirstLine = function(srcPath, destPath, done) { 

    var rl = readline.createInterface({ 
    input: fs.createReadStream(srcPath) 
    }); 
    var output = fs.createWriteStream(destPath); 
    var firstRemoved = false; 

    rl.on('line', (line) => { 
    if(!firstRemoved) { 
     firstRemoved = true; 
     return; 
    } 
    output.write(line + '\n'); 
    }).on('close',() => { 
    return done(); 
    }) 
} 

и может быть легко изменен, чтобы удалить определенное количество линий, путем изменения «firstRemoved» в счетчике:

var linesRemoved = 0; 
... 
if(linesRemoved < LINES_TO_BE_REMOVED) { 
    linesRemoved++; 
    return; 
} 
...