Node.js 스트림의 내용을 문자열 변수로 어떻게 읽습니까?
smtp-protocol
SMTP 이메일을 캡처하고 메일 데이터를 처리 하는 데 사용하는 Node 프로그램을 해킹하고 있습니다. 라이브러리는 메일 데이터를 스트림으로 제공하며 문자열로 가져 오는 방법을 모르겠습니다.
나는 현재 그것을 stdout에 쓰고 stream.pipe(process.stdout, { end: false })
있지만 말했듯이 스트림 데이터가 대신 문자열로 필요하며 스트림이 끝나면 사용할 수 있습니다.
Node.js 스트림의 모든 데이터를 문자열로 수집하려면 어떻게해야합니까?
핵심은 Readable Stream 의 data
및 end
이벤트 를 사용하는 것 입니다. 다음 이벤트를 들어보십시오.
stream.on('data', (chunk) => { ... });
stream.on('end', () => { ... });
data
이벤트 를 수신하면 데이터를 수집하기 위해 생성 된 버퍼에 새 데이터 청크를 추가합니다.
end
이벤트 를 받으면 필요한 경우 완료된 버퍼를 문자열로 변환합니다. 그런 다음 필요한 작업을 수행하십시오.
위의 답변보다 유용하기를 바랍니다.
var string = '';
stream.on('data',function(data){
string += data.toString();
console.log('stream data ' + part);
});
stream.on('end',function(){
console.log('final output ' + string);
});
문자열 연결은 문자열 부분을 수집하는 가장 효율적인 방법은 아니지만 단순성을 위해 사용됩니다 (그리고 코드가 효율성에 관심이 없을 수도 있음).
또한이 코드는 비 ASCII 텍스트에 대해 예측할 수없는 오류를 생성 할 수 있지만 (모든 문자가 한 바이트에 맞는다고 가정 함) 아마도 당신은 그것에 대해 신경 쓰지 않을 것입니다.
위의 어느 것도 나를 위해 일하지 않았습니다. Buffer 개체를 사용해야했습니다.
const chunks = [];
readStream.on("data", function (chunk) {
chunks.push(chunk);
});
// Send the buffer or you can put it into a var
readStream.on("end", function () {
res.send(Buffer.concat(chunks));
});
또 다른 방법은 스트림을 promise로 변환하고 (아래 예제 참조) then
(또는 await
)을 사용 하여 해결 된 값을 변수에 할당하는 것입니다.
function streamToString (stream) {
const chunks = []
return new Promise((resolve, reject) => {
stream.on('data', chunk => chunks.push(chunk))
stream.on('error', reject)
stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')))
})
}
const result = await streamToString(stream)
일반적으로이 간단한 함수를 사용하여 스트림을 문자열로 변환합니다.
function streamToString(stream, cb) {
const chunks = [];
stream.on('data', (chunk) => {
chunks.push(chunk.toString());
});
stream.on('end', () => {
cb(chunks.join(''));
});
}
사용 예 :
let stream = fs.createReadStream('./myFile.foo');
streamToString(stream, (data) => {
console.log(data); // data is now my string variable
});
nodejs 문서 에서이 작업을 수행해야합니다. 인코딩이 단지 한 무리의 바이트라는 것을 알지 못한 채 문자열을 항상 기억하십시오.
var readable = getReadableStreamSomehow();
readable.setEncoding('utf8');
readable.on('data', function(chunk) {
assert.equal(typeof chunk, 'string');
console.log('got %d characters of string data', chunk.length);
})
스트림에는 .toString()
(내가 이해하는) 간단한 기능이나 (내가 이해 .toStringAsync(cb)
하지 못하는) 기능 과 같은 것이 없습니다.
그래서 나만의 도우미 기능을 만들었습니다.
var streamToString = function(stream, callback) {
var str = '';
stream.on('data', function(chunk) {
str += chunk;
});
stream.on('end', function() {
callback(str);
});
}
// how to use:
streamToString(myStream, function(myStr) {
console.log(myStr);
});
나는 다음과 같이 더 많은 행운을 얻었습니다.
let string = '';
readstream
.on('data', (buf) => string += buf.toString())
.on('end', () => console.log(string));
나는 노드를 사용 v9.11.1
하고는 readstream
a로부터 반응이다 http.get
콜백.
인기있는 (주간 다운로드 5 백만 회 이상) 가벼운 get-stream 라이브러리를 사용하는 쉬운 방법 :
https://www.npmjs.com/package/get-stream
const fs = require('fs');
const getStream = require('get-stream');
(async () => {
const stream = fs.createReadStream('unicorn.txt');
console.log(await getStream(stream)); //output is string
})();
스트림 감속기와 같은 것은 어떻습니까?
다음은 ES6 클래스를 사용하는 예제입니다.
var stream = require('stream')
class StreamReducer extends stream.Writable {
constructor(chunkReducer, initialvalue, cb) {
super();
this.reducer = chunkReducer;
this.accumulator = initialvalue;
this.cb = cb;
}
_write(chunk, enc, next) {
this.accumulator = this.reducer(this.accumulator, chunk);
next();
}
end() {
this.cb(null, this.accumulator)
}
}
// just a test stream
class EmitterStream extends stream.Readable {
constructor(chunks) {
super();
this.chunks = chunks;
}
_read() {
this.chunks.forEach(function (chunk) {
this.push(chunk);
}.bind(this));
this.push(null);
}
}
// just transform the strings into buffer as we would get from fs stream or http request stream
(new EmitterStream(
["hello ", "world !"]
.map(function(str) {
return Buffer.from(str, 'utf8');
})
)).pipe(new StreamReducer(
function (acc, v) {
acc.push(v);
return acc;
},
[],
function(err, chunks) {
console.log(Buffer.concat(chunks).toString('utf8'));
})
);
The cleanest solution may be to use the "string-stream" package, which converts a stream to a string with a promise.
const streamString = require('stream-string')
streamString(myStream).then(string_variable => {
// myStream was converted to a string, and that string is stored in string_variable
console.log(string_variable)
}).catch(err => {
// myStream emitted an error event (err), so the promise from stream-string was rejected
throw err
})
This worked for me and is based on Node v6.7.0 docs:
let output = '';
stream.on('readable', function() {
let read = stream.read();
if (read !== null) {
// New stream data is available
output += read.toString();
} else {
// Stream is now finished when read is null.
// You can callback here e.g.:
callback(null, output);
}
});
stream.on('error', function(err) {
callback(err, null);
})
setEncoding('utf8');
Well done Sebastian J above.
I had the "buffer problem" with a few lines of test code I had, and added the encoding information and it solved it, see below.
Demonstrate the problem
software
// process.stdin.setEncoding('utf8');
process.stdin.on('data', (data) => {
console.log(typeof(data), data);
});
input
hello world
output
object <Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64 0d 0a>
Demonstrate the solution
software
process.stdin.setEncoding('utf8'); // <- Activate!
process.stdin.on('data', (data) => {
console.log(typeof(data), data);
});
input
hello world
output
string hello world
Using the quite popular stream-buffers
package which you probably already have in your project dependencies, this is pretty straightforward:
// imports
const { WritableStreamBuffer } = require('stream-buffers');
const { promisify } = require('util');
const { createReadStream } = require('fs');
const pipeline = promisify(require('stream').pipeline);
// sample stream
let stream = createReadStream('/etc/hosts');
// pipeline the stream into a buffer, and print the contents when done
let buf = new WritableStreamBuffer();
pipeline(stream, buf).then(() => console.log(buf.getContents().toString()));
And yet another one for strings using promises:
function getStream(stream) {
return new Promise(resolve => {
const chunks = [];
stream.on("data", chunk => chunks.push(chunk));
stream.on("end", () => resolve(Buffer.concat(chunks).toString()));
});
}
Usage:
const stream = fs.createReadStream(__filename);
getStream(stream).then(r=>console.log(r));
remove the .toString()
to use with binary Data if required.
'development' 카테고리의 다른 글
C ++의 문자열로 파일 내용 읽기 (0) | 2020.10.20 |
---|---|
2 차원 문자열 배열을 어떻게 선언 할 수 있습니까? (0) | 2020.10.20 |
Android Studio는 계속해서 지원되지 않는 major.minor 버전 52.0을받습니다. (0) | 2020.10.20 |
CALayer를 즉시 이동하는 방법 (애니메이션없이) (0) | 2020.10.20 |
Objective-C의 반올림 숫자 (0) | 2020.10.20 |