2 strumienie:Łączy dwie (lub n) strumieni
Biorąc czytelny streams
stream1
istream2
, co to jest idiomatyczne (zwięzły) sposobem uzyskać strumień zawierającystream1
istream2
łączone?Nie mogę wykonać
stream1.pipe(outStream); stream2.pipe(outStream)
, ponieważ wtedy zawartość strumienia jest pomieszana.n strumienie:
Biorąc pod EventEmitter emitującego nieokreślona liczba strumieni, na przykład
eventEmitter.emit('stream', stream1) eventEmitter.emit('stream', stream2) eventEmitter.emit('stream', stream3) ... eventEmitter.emit('end')
co to jest idiomatyczne (zwięzły) sposobem uzyskać strumień ze wszystkich strumieni sklejone?
Odpowiedz
Pakiet combined-stream łączy strumienie. Przykład z README:
var CombinedStream = require('combined-stream');
var fs = require('fs');
var combinedStream = CombinedStream.create();
combinedStream.append(fs.createReadStream('file1.txt'));
combinedStream.append(fs.createReadStream('file2.txt'));
combinedStream.pipe(fs.createWriteStream('combined.txt'));
Uważam, że musisz dodać wszystkie strumienie naraz. Jeśli kolejka jest pusta, automatycznie kończy się combinedStream
. Zobacz issue #5.
Biblioteka stream-stream jest alternatywą, która ma wyraźne oznaczenie .end
, ale jest znacznie mniej popularna i prawdopodobnie nie jest tak dobrze przetestowana. Używa API streams2 węzła 0.10 (patrz this discussion).
Możesz być w stanie uczynić go bardziej zwięzły, ale tutaj jest jeden, który działa:
var util = require('util');
var EventEmitter = require('events').EventEmitter;
function ConcatStream(streamStream) {
EventEmitter.call(this);
var isStreaming = false,
streamsEnded = false,
that = this;
var streams = [];
streamStream.on('stream', function(stream){
stream.pause();
streams.push(stream);
ensureState();
});
streamStream.on('end', function() {
streamsEnded = true;
ensureState();
});
var ensureState = function() {
if(isStreaming) return;
if(streams.length == 0) {
if(streamsEnded)
that.emit('end');
return;
}
isStreaming = true;
streams[0].on('data', onData);
streams[0].on('end', onEnd);
streams[0].resume();
};
var onData = function(data) {
that.emit('data', data);
};
var onEnd = function() {
isStreaming = false;
streams[0].removeAllListeners('data');
streams[0].removeAllListeners('end');
streams.shift();
ensureState();
};
}
util.inherits(ConcatStream, EventEmitter);
Mamy śledzić stan z streams
(kolejkę strumieni; push
do tyłu i shift
od z przodu), isStreaming
i streamsEnded
. Kiedy dostaniemy nowy strumień, popychamy go, a gdy skończy się strumień, przestajemy go słuchać i przesuwać. Po zakończeniu strumienia strumieni ustawiamy streamsEnded
.
Na każdym z tych zdarzeń sprawdzamy stan, w którym się znajdujemy. Jeśli jesteśmy już streamowani (przesyłamy strumień), nie robimy nic. Jeśli kolejka jest pusta i ustawiona jest streamsEnded
, emitujemy zdarzenie end
. Jeśli coś jest w kolejce, wznawiamy je i słuchamy jego zdarzeń.
* Należy pamiętać, że pause
i resume
mają charakter doradczy, więc niektóre strumienie mogą nie działać poprawnie i wymagać buforowania. To ćwiczenie należy do czytelnika.
Uczyniwszy to wszystko, chciałbym zrobić sprawę n=2
przez konstruowania EventEmitter
, tworząc ConcatStream
z nim, i emitując dwa stream
wydarzenia następnie zdarzenia end
. Jestem pewien, że można to zrobić bardziej zwięźle, ale równie dobrze możemy wykorzystać to, co mamy.
streamee.js to zestaw transformatorów strumieniowych i kompozytorów opartych na węźle 1.0+ strumieni i obejmują sposób oddzielając:
var stream1ThenStream2 = streamee.concatenate([stream1, stream2]);
Dzięki, sprawdzę to. To Węzeł 0.10 Zakładam? –
Tak Węzeł 0.10, ale można zawijać strumienie w starym stylu do strumieni 0.10+, jak napisano w README – atamborrino
https://github.com/joepie91/node-combined-stream2 jest Streams2 zgodny wymiana spadek w modułu łączy strumienia (który jest opisany powyżej.) Automatycznie owija Streams1 strumienie.
kod Przykład skojarzonym stream2:
var CombinedStream = require('combined-stream2');
var fs = require('fs');
var combinedStream = CombinedStream.create();
combinedStream.append(fs.createReadStream('file1.txt'));
combinedStream.append(fs.createReadStream('file2.txt'));
combinedStream.pipe(fs.createWriteStream('combined.txt'));
może być wykonane z wanilii nodejs
import { PassThrough } from 'stream'
const merge = (...streams) => {
let pass = new PassThrough()
let waiting = streams.length
for (let stream of streams) {
pass = stream.pipe(pass, {end: false})
stream.once('end',() => --waiting === 0 && pass.emit('end'))
}
return pass
}
prosty reduce operacja powinna być dobrze w nodejs!
const {PassThrough} = require('stream')
let joined = [s0, s1, s2, ...sN].reduce((pt, s, i, a) => {
s.pipe(pt, {end: false})
s.once('end',() => a.every(s => s.ended) && pt.emit('end'))
return pt
}, new PassThrough())
Pozdrawiam;)
Czy nie powinieneś zwracać czegoś z redukcji? Wygląda na to, że 'join' będzie niezdefiniowany. Naprawiono –
. dzięki;) @Mark_M – Ivo
OSTRZEŻENIE: Spowoduje to równoległe przesyłanie wszystkich strumieni do strumienia PassThrough, bez żadnych szacunków dotyczących kolejności danych, co bardziej niż prawdopodobne uszkodzenie danych. –
- 1. łączy dwie tabele z zerowalnym kluczem obcym?
- 2. Zagnieżdżona kwerenda lub łączy
- 3. Jak połączyć dwa lub więcej strumieni
- 4. MinMaxPriorityQueue przy użyciu strumieni Java
- 5. Dwie funkcje lub parametr boolowski?
- 6. Jak połączyć dwa lub więcej plików/strumieni gzip
- 7. Łączenie strumieni podłańcuchów
- 8. Android RxJava łączy listę
- 9. SQL Multiple Łączy
- 10. Wklej wszystkie możliwe przekątne matrycy n * n lub ramki danych
- 11. Zastępowanie strumieni C++
- 12. Generowanie krótkich [] strumieni używanych
- 13. Jak działa buforowanie strumieni?
- 14. MySQL Insert & Łączy
- 15. Ocena na dwie lub więcej list
- 16. Łączy dwa Func delegatów
- 17. Łączy w JavaScript
- 18. Zamykanie strumieni, zawsze konieczne? .net
- 19. Śledzenie twardych lub symbolicznych łączy z rtęcią w systemie Windows
- 20. Tworzenie strumienia Node.js z dwóch potokowych strumieni
- 21. Generowanie wszystkich możliwych permutacji (lub n-krotki)
- 22. Usuń \ n lub \ tz określonego ciągu
- 23. Mikrousługi i baza danych łączy
- 24. Łączy dwa dataframes PySpark
- 25. Jak dlmalloc łączy cząstki?
- 26. subwersja łączy polecenie usuwania
- 27. łączy względne adresy URL?
- 28. Łączy Mat w OpenCV
- 29. Multiple zewnętrzna łączy semantykę
- 30. SQL Łączy smyczkowy Wynik
Dzięki Aaron! Miałem nadzieję, że będzie istniejąca biblioteka, więc mogę rozwiązać ją w trzech linijkach. Jeśli nie, myślę, że mogę wyodrębnić twoje rozwiązanie do paczki. Czy mogę użyć Twojego kodu na licencji MIT? –
Ah, odnaleziono bibliotekę strumieni strumieniowych. Zobacz moją odpowiedź. –
@JoLiss Również najpierw szukałem czegoś, ale nie znalazłem tej opcji. Z pewnością możesz użyć mojego kodu w bibliotece, jeśli nadal chcesz. –