Я пишу довольно простое приложение для преобразования данных - читайте один файл и пишите на другой. Файлы относительно большие - 2 ГБ. Тем не менее, я обнаружил, что флеш в файловой системе не происходит, в цикле пробки-пробки это происходит только в конце(), поэтому end() в основном зависает системой до тех пор, пока она полностью не погаснет. Я упростил пример, поэтому он просто пишет строку в поток много раз.NODEJS: метод Uncork() для записываемого потока на самом деле не очищает данные
var PREFIX = 'E:\\TEST\\';
var line = 'AA 11 999999999 20160101 123456 20160101 AAA 00 00 00 0 0 0 2 2 0 0 20160101 0 00';
var fileSystem = require('fs');
function writeStrings() {
var stringsCount = 0;
var stream = fileSystem.createWriteStream(PREFIX +'output.txt');
stream.once('drain', function() {
console.log("drained");
});
stream.once('open', function (fileDescriptor) {
var started = false;
console.log('writing file ');
stream.cork();
for (i = 0; i < 2000000; i++) {
stream.write(line + i);
if (i % 10000 == 0) {
// console.log('passed ',i);
}
if (i % 100000 == 0) {
console.log('uncorcked ',i,stream._writableState.writing);
stream.uncork();
stream.cork();
}
}
stream.end();
});
stream.once('finish', function() {
console.log("done");
});
}
writeStrings();
происходит внутри узла _stream_writable.js, я обнаружил, что он очищает буфер только при этом условии:
if (!state.writing &&
!state.corked &&
!state.finished &&
!state.bufferProcessing &&
state.buffer.length)
clearBuffer(this, state);
и, как вы можете видеть из примера, флаг письма не установлен назад после первого uncork(), который предотвращает разворачивание откупоривателя. Кроме того, я не вижу, чтобы события утечки вызывали вообще. Игра с highWaterMark не помогает (на самом деле, похоже, не влияет на что-либо). Вручную установить запись в false (+ некоторые другие флаги) действительно помогло, но это, безусловно, неправильно. Я не понимаю концепцию этого?
Я собирался сказать, что вам нужно вызвать первый 'stream.cork()' вне цикла 'for', но, судя по вашему редактированию, это уже реальная ситуация? – robertklep
Да, действительно. На самом деле я сейчас не вижу «открытое» событие в документации на узел, и я просто брожу туда, где я его принимаю. Однако остается вопрос - как можно просто написать кучу строк внутри файла, контролируя промывку? Потому что он делает то, что делает, но только один раз. – Andrey
Не смотря на это слишком глубоко, я думаю, что это связано с написанием, поэтому 'uncork()', будучи асинхронным. Пока собранный буфер все еще записывается, ваш код продолжает работать (следовательно, флаг 'writing' является истинным). Кроме того, насколько я понимаю документы, «утечка» испускается, когда безопасно писать, а не когда внутренний буфер, используемый для 'cork()', был исчерпан. – robertklep