Włamuję się do programu Node, który używa smtp-protocol
do przechwytywania e-maili SMTP i działania na danych poczty. Biblioteka dostarcza dane poczty w postaci strumienia i nie wiem, jak zamienić je w łańcuch.
Obecnie piszę go na stdout stream.pipe(process.stdout, { end: false })
, ale jak powiedziałem, potrzebuję zamiast tego danych strumienia w ciągu, którego mogę użyć po zakończeniu strumienia.
Jak zebrać wszystkie dane ze strumienia Node.js w ciągu?
javascript
node.js
stream
obrienmd
źródło
źródło
Odpowiedzi:
(Ta odpowiedź pochodzi sprzed lat, kiedy była to najlepsza odpowiedź. Jest teraz lepsza odpowiedź poniżej. Nie śledziłem node.js i nie mogę usunąć tej odpowiedzi, ponieważ jest oznaczona jako „poprawna w tym pytaniu ". Jeśli myślisz o kliknięciu w dół, co mam zrobić?)
Kluczem jest wykorzystanie
data
iend
zdarzeń o czytelnej Stream . Posłuchaj tych wydarzeń:Po otrzymaniu
data
zdarzenia dodaj nową porcję danych do buforu utworzonego w celu gromadzenia danych.Po odebraniu
end
zdarzenia przekonwertuj wypełniony bufor na ciąg, jeśli to konieczne. Następnie zrób z tym, co musisz.źródło
Innym sposobem byłoby przekonwertowanie strumienia na obietnicę (patrz przykład poniżej) i użycie
then
(lubawait
) w celu przypisania rozstrzygniętej wartości do zmiennej.źródło
SyntaxError: await is only valid in async function
. Co ja robię źle?streamToString(stream).then(function(response){//Do whatever you want with response});
.toString("utf8")
na końcu, aby uniknąć problemu błędu dekodowania, jeśli fragment zostanie podzielony w środku znaku wielobajtowego; (2) faktyczna obsługa błędów; (3) umieszczenie kodu w funkcji, aby można go było ponownie wykorzystać, a nie skopiować i wkleić; (4) użycie Promises, aby można było włączyć funkcjęawait
; (5) mały kod, który nie przeciąga miliona zależności, w przeciwieństwie do niektórych bibliotek npm; (6) Składnia ES6 i nowoczesne najlepsze praktyki.Uncaught TypeError [ERR_INVALID_ARG_TYPE]: The "list[0]" argument must be an instance of Buffer or Uint8Array. Received type string
jeśli strumieństring
zamiast tego tworzy fragmentyBuffer
. Używaniechunks.push(Buffer.from(chunk))
powinno działać zarówno z fragmentami, jakstring
iBuffer
.Żadne z powyższych nie działało dla mnie. Musiałem użyć obiektu Buffer:
źródło
Mam nadzieję, że jest to bardziej przydatne niż powyższa odpowiedź:
Zwróć uwagę, że konkatenacja ciągów nie jest najbardziej wydajnym sposobem zbierania części ciągów, ale jest używana dla uproszczenia (i być może twój kod nie dba o wydajność).
Ponadto kod ten może powodować nieprzewidywalne błędy w przypadku tekstu innego niż ASCII (zakłada, że każdy znak mieści się w bajcie), ale być może też Cię to nie obchodzi.
źródło
join("")
tablicę na końcu.Zwykle używam tej prostej funkcji, aby przekształcić strumień w ciąg:
Przykład użycia:
źródło
chunks.push(chunk.toString());
I jeszcze jeden dla stringów używających obietnic:
Stosowanie:
usuń,
.toString()
aby używać z danymi binarnymi, jeśli to konieczne.aktualizacja : @AndreiLED poprawnie wskazał, że ma to problemy ze stringami. Nie mogłem uzyskać strumienia zwracającego ciągi znaków z wersją węzła, którą mam, ale interfejs API zauważa, że jest to możliwe.
źródło
Uncaught TypeError [ERR_INVALID_ARG_TYPE]: The "list[0]" argument must be an instance of Buffer or Uint8Array. Received type string
jeśli strumieństring
zamiastBuffer
. Używaniechunks.push(Buffer.from(chunk))
powinno działać zarówno z fragmentami, jakstring
iBuffer
.Z dokumentacji nodejs powinieneś to zrobić - zawsze pamiętaj o łańcuchu, nie wiedząc, że kodowanie to tylko kilka bajtów:
źródło
Strumienie nie mają prostej
.toString()
funkcji (którą rozumiem) ani czegoś w rodzaju.toStringAsync(cb)
funkcji (której nie rozumiem).Stworzyłem więc własną funkcję pomocniczą:
źródło
Miałem więcej szczęścia używając w ten sposób:
Używam węzła
v9.11.1
ireadstream
jest odpowiedzią zhttp.get
wywołania zwrotnego.źródło
Najczystszym rozwiązaniem może być użycie pakietu „string-stream”, który konwertuje strumień na łańcuch z obietnicą.
źródło
Łatwy sposób dzięki popularnej (ponad 5 mln pobrań tygodniowo) i lekkiej bibliotece Get Stream :
https://www.npmjs.com/package/get-stream
źródło
A co z czymś takim jak reduktor strumienia?
Oto przykład użycia klas ES6, jak z nich korzystać.
źródło
To zadziałało dla mnie i jest oparte na dokumentacji Node v6.7.0 :
źródło
setEncoding ('utf8');
Dobra robota, Sebastian J. powyżej.
Miałem „problem z buforem” z kilkoma wierszami kodu testowego, które miałem, dodałem informacje o kodowaniu i rozwiązałem go, patrz poniżej.
Zademonstruj problem
oprogramowanie
Wejście
wynik
Zademonstruj rozwiązanie
oprogramowanie
Wejście
wynik
źródło
Wszystkie wymienione odpowiedzi wydają się otwierać strumień do odczytu w trybie płynnym, który nie jest domyślny w NodeJS i może mieć ograniczenia, ponieważ nie ma wsparcia dla ciśnienia wstecznego, które NodeJS zapewnia w trybie wstrzymanego odczytu strumienia. Oto implementacja wykorzystująca Just Buffers, Native Stream i Native Stream Transforms oraz wsparcie dla Object Mode
źródło
Co o tym myślisz ?
źródło
Korzystając z dość popularnego
stream-buffers
pakietu, który prawdopodobnie masz już w zależnościach projektu, jest to dość proste:źródło
W moim przypadku nagłówki odpowiedzi typu zawartości to Content-Type: text / plain . Czytałem więc dane z bufora, takie jak:
źródło