Я пытаюсь реализовать подпрограмму для Node.js, которая позволила бы открыть файл, к которому в данный момент добавляется какой-то другой процесс, а затем сразу же возвращать порции данных, когда они добавляются в файл. Считается, что она похожа на tail -f
UNIX tail -f
, однако действует немедленно, когда доступны фрагменты, а не опрашивает изменения во времени. В качестве альтернативы, вы можете думать об этом как о работе с файлом, так же как и с сокетом - ожидая, что время on('data')
будет срабатывать до тех пор, пока файл не будет закрыт явно.
В C land, если бы я это реализовал, я бы просто открыл файл, передал его дескриптор файла в select()
(или любую альтернативную функцию с аналогичным обозначением), а затем просто прочитал куски, так как дескриптор файла помечен как "читаемый". Таким образом, когда нечего читать, оно не будет читаемым, а когда что-то добавляется в файл, оно снова читается.
Я несколько ожидал такого поведения для следующего примера кода в Javascript:
function readThatFile(filename) {
const stream = fs.createReadStream(filename, {
flags: 'r',
encoding: 'utf8',
autoClose: false // I thought this would prevent file closing on EOF too
});
stream.on('error', function(err) {
// handle error
});
stream.on('open', function(fd) {
// save fd, so I can close it later
});
stream.on('data', function(chunk) {
// process chunk
// fs.close() if I no longer need this file
});
}
Тем не менее, этот пример кода просто вылетает при обнаружении EOF, поэтому я не могу дождаться появления нового чанка. Конечно, я мог бы переопределить это, используя fs.open
и fs.read
, но это несколько fs.read
цели Node.js
В качестве альтернативы я мог бы fs.watch()
файл fs.watch()
для изменений, но он не будет работать по сети, и мне не нравится идея постоянно открывать файл вместо того, чтобы просто держать его открытым.
Я пытался сделать это:
const fd = fs.openSync(filename, 'r'); // sync for readability' sake
const stream = net.Socket({ fd: fd, readable: true, writable: false });
Но не повезло - net.Socket
не устраивает и выдает TypeError: Unsupported fd type: FILE
.
Итак, какие-либо решения?