2017-02-11 3 views
0

Я обнаружил, что write() метод stream.Writable класс не записывает данные последовательно. Когда я отправляю приложение на сервер в куски, этот код собирает куски данных в неправильном порядке, если не происходит никаких задержек. Если я помещаю сообщение отладки, такое как console.log() в середине цикла (например, чтобы сбросить данные, чтобы посмотреть, что написано, на самом деле), эта ошибка исчезает. Итак, каково состояние гонки в этом коде? Похоже, я выполняю последовательную сборку файла, поэтому я не понимаю, что не так.write() не пишет последовательный?

Мой код:

function join_chunks(company_id,attachment_id,num_chunks) { 
    var stream; 
    var file; 
    var output_filename=ATTACHMENTS_PATH + '/comp' + company_id + '/' + attachment_id + '.data'; 
    var input_filename; 
    var chunk_data; 
    var chunk_count=0; 
    stream=fs.createWriteStream(output_filename,{flags:'w+',mode: 0666}); 
    console.log('joining files:'); 
    for(var i=0;i<num_chunks;i++) { 
     input_filename=ATTACHMENTS_PATH + '/comp' + company_id + '/' + attachment_id + '-' + (i+1) + '.chunk'; 
     console.log(input_filename); 
     fs.readFile(input_filename , (err, chunk_data) => { 
      if (err) throw err; 
      stream.write(chunk_data,function() { 
       chunk_count++; 
       if (chunk_count==num_chunks) { 
        console.log('join finished. closing stream'); 
        stream.end(); 
       } 
      }); 
     }); 
    } 
} 

консоль: версия

joining files: 
/home/attachments/comp-2084830518/67-1.chunk 
/home/attachments/comp-2084830518/67-2.chunk 
/home/attachments/comp-2084830518/67-3.chunk 
/home/attachments/comp-2084830518/67-4.chunk 
join finished. closing stream 

Node: v6.9.2

+2

'fs.readFile' является асинхронным; вы немедленно ставите в очередь операции с файлами num_chunks, но они не обязательно будут завершены в том порядке, в котором вы их ставили в очередь. Вам, вероятно, придется подождать, пока они все не закончатся, а затем привести их в порядок и написать их. – qxz

+0

@qxz, хороший глаз. чтение было проблемой, а не записью. Я заменил чтение последовательным потоком, и все работает нормально. Если вы ответите на вопрос, я его приму. Другой ответ неверен. – Nulik

ответ

1

stream.write является асинхронной операцией. Это означает, что несколько обращений к нему могут быть обслужены не в порядке.

Если вы хотите, чтобы ваши записи выполнялись по порядку, используйте stream.writeSync или используйте аргумент обратного вызова stream.write, чтобы упорядочить ваши записи.

+0

Спасибо. Есть ли где-то в документации, говорящей, что метод Writable.write() выполняется не по порядку? Или где вы это читали? – Nulik

+0

Как я понимаю, поток 'Writable' был создан для последовательной записи, поэтому он должен поддерживать порядок по умолчанию в режиме FIFO. – Nulik

+0

@Nulik Вообще говоря, все системные вызовы в узле асинхронны, если в документации явно не указано иначе. Помимо явных точек синхронизации, таких как обратные вызовы, нет никаких гарантий относительно порядка асинхронных вызовов. – duskwuff

Смежные вопросы