NodeJS Butter Stream


バッファ

  • 固定サイズのメモリブロック
  • メモリ内のデータ(バイト単位)自体が
  • である.
  • 汎用出力
  • に近い配列形式//配列であれば、出力はアスキーコードである.
  • Fixed-size chuck of memory
  • array of integers, byte of data
  • const fs = require("fs");
    
    const buf = Buffer.from("Hi");
    console.log(buf); //-> <Buffer 48 69> 유니코드 형태
    console.log(buf.length); //->2
    console.log(buf[0]); //->72 아스키코드형태
    console.log(buf[1]); //->105 아스키코드형태
    console.log(buf.toString()); 
    //-> 문자형태로 출력(기본값 : 'utf-8' , 옵션 전달 가능)
    
    //create : buffer 생성
    const buf2 = Buffer.alloc(2); 
    //-> 사이즈가 2개인 buffer를 만듦. 사용가능한 메모리를 찾아 초기화시켜줌
    
    buf2[0] = 72;
    buf2[1] = 105;
    console.log(buf2); //-> <Buffer 48 69>
    console.log(buf2.toString()); //-> Hi
    
    //alloUnsafe : 초기화하지 않기 때문에 빠름, but 데이터가 들어있을 수 있기 때문에 초기화하는 것이 좋음
    const buf3 = Buffer.allocUnsafe(2);
    
    buf2.copy(buf3); //-> buf2에 있는 값을 buf3에 copy
    
    //concat : 여러 버퍼를 모을 수 있다.
    const newBuf = Buffer.concat([buf, buf2, buf3]);
    

    ながれ

  • ストリームは、バッファ単位で処理するのではなく、
  • 単位でファイルを転送する.
  • ストリームの読み取りまたは書き込みが可能であり、すべてのストリームオブジェクトがEventEmitterインスタンス
  • である.

    Readable

    const fs = require("fs");
    
    // stream에서 데이터가 조금씩 도착하면 알려줌
    const readStream = fs.createReadStream("./file.txt", {
      highWaterMark: 80, // 기본값 : 64 kbyts
      encoding: "utf-8",
    });
    
    const data = [];
    //on : 데이터가 발생할 때마다 콜백함수 실행, 자기자신을 return
    readStream.on("data", chunk => {
      data.push(chunk);
      console.count("data");
    });
    
    //once : 한번만 실행
    readStream.once("data", chunk => {
      data.push(chunk);
      console.count("data");
    });
    
    //-> 모든 데이터가 read되었을 때 실행
    readStream.on("end", () => {
      console.log(data.join(""));
      console.log("success");
    });
    
    readStream.on("error", error => {
      console.log(error);
    });

    Writable

    const fs = require("fs");
    
    // file3 파일을 생성하여 (helloworld!!!!!)값을 write
    const writeStream = fs.createWriteStream("./file3.txt");
    writeStream.on("finish", () => {
      console.log("finised");
    });
    
    writeStream.write("hello");
    writeStream.write("world");
    writeStream.write("!!!!!");
    
    writeStream.end();

    Readable & Writable

    const fs = require('fs');
    
    let inF = fs.createReadStream('./aaa.txt', {
      highWaterMark: 10, 
      encoding: 'utf-8', // 설정해주지 않으면 Buffer 형태로 나온다.
    });
    let outF = fs.createWriteStream('./bbb.txt');
    
    inF.on('data', function (fileData) {
      console.log(fileData);
      outF.write(fileData); //-> 버퍼가 채워지는대로 바로바로 outF에 write해준다.
    });
    
    inF.on('end', function () {
      console.log('읽기 종료');
      outF.end(function () {
        console.log('쓰기 종료');
      });
    });

    pipe

    const fs = require('fs');
    
    const readStream = fs.createReadStream('./aaa.txt');
    const writeStream = fs.createWriteStream('./ccc.txt');
    
    const piping = readStream.pipe(writeStream);
    
    piping.on('finish', () => {
      console.log('done!!');
    });
    // -> ccc 파일을 생성하여 readStream의 데이터를 그대로 전달.
    Readble&Writableのサンプルコードのように、データはバッファ単位で転送されます.

    圧縮zilb

    const fs = require('fs');
    const zlib = require('zlib'); //압출 모듈
    
    const readStream = fs.createReadStream('./file.txt');
    const zlibStream = zlib.createGzip();
    const writeStream = fs.createWriteStream('./file4.zip');
    
    const pining = readStream.pipe(zlibStream).pipe(writeStream); // 압축한 형태로 file4에 데이터를 전달.
    piping.on('finish', () => {
      console.log('done!!');
    });

    サーバリクエスト時

    const http = require('http');
    const server = http.createServer((req, res) => {
      fs.readFile('file.txt', (err, data) => {
        res.end(data);
      });
    });
    server.listen(3000);
    以上のように、ファイルをすべて読み込み、データを送信します.
    ただし、ストリームを使用する場合は、次の操作を行います.
    const http = require('http');
    const server = http.createServer((req, res) => {
      const stream = fs.createReadStream('./file.txt');
      stream.pipe(res);
    });
    server.listen(3000);
    バッファ転送が可能です.