본문 바로가기

4. Node.js | React.js

4/18(화) IT K-DT(34일차) / 7.OS~14.pipe

7. OS

내장 모듈 중 하나로, 운영체제와 상호작용이 가능하게 하는 모듈.

운영체제에 대한 정보를 얻거나 시스템 작업을 수행할 수 있음.

os 모듈을 사용하여 시스템 메모리, CPU, 네트워크 인터페이스 등의 정보를 가져오고 시스템 자원을 관리.

 

os 변수를 지정하여 os 모듈을 불러옴.


const os = require('os');


 EOL(End Of Line)
 개행 문자. 텍스트 파일 내의 각 행(line)이 끝나는 위치를 나타내는 문자 또는 문자열.
 텍스트 파일을 읽거나 쓸 때 적절한 개행 문자열을 사용하는 것이 중요

 맥OS: \n
 Windows: \r \n

 

사용하는 OS와 관련된 정보를 확인.


console.log( os.totalmem() ); // 16961626112 // 총 메모리 확인.

console.log( os.freemem() ); // 10817413120  // 현재 남은 메모리의 확인.

console.log( os.type() ); // Windows_NT // OS의 종류.

console.log( os.userInfo() ); // 사용자의 정보.
  {
     uid: -1,
     gid: -1,
     username: 'Administrator',
     homedir: 'C:\\Users\\Administrator',
     shell: null
  }

console.log( os.cpus() ); // 어떤 CPU를 사용하는지 확인.
 [
     {
       model: '12th Gen Intel(R) Core(TM) i7-12700',
       speed: 2112,
       times: { user: 22125, nice: 0, sys: 38625, idle: 5735812, irq: 937 }
     },
 ... 
     {
       model: '12th Gen Intel(R) Core(TM) i7-12700',
       speed: 2112,
       times: { user: 229468, nice: 0, sys: 247734, idle: 5318890, irq: 2984 }
     }
 ]

console.log( os.homedir() ); // C:\Users\Administrator // CPU의 home 디렉토리.

console.log( os.hostname() ); // DESKTOP-HUJUVSS  // 사용자의 이름.



 

8. process

현재 실행 중인 프로세스와 관련된 정보를 제공하는 모듈.

이 모듈을 사용하여 현재 실행중인 Node.js 프로세스에 대한 정보를 얻을 수 있으며,

이를 통해 프로세스의 환경 변수, 실행 매개 변수, 작업 디렉토리 등을 조작할 수 있음.

 

process 변수를 지정하여 process 모듈을 불러옴.


const process = require('process');


console.log( process.execPath ); // 실행되는 node가 있는 경로 위치.   (프로퍼티이므로 소괄호가 없음.)
// C:\Program Files\nodejs\node.exe. 

console.log( process.version );  // node의 버전 // v18.16.0 

console.log( process.pid ); // process의 ID.(node가 동작하는 process의 할당번호) // 9672 

console.log( process.ppid ); // 부모process의 ID. (node의 실제 ID.) // 6452 

console.log( process.platform ); // win32

console.log( process.env ); // process의 환경변수. (node의 편리한 사용이 가능하도록 하는 역할.)
 {
     ALLUSERSPROFILE: 'C:\\ProgramData',
     APPDATA: 'C:\\Users\\Administrator\\AppData\\Roaming',
 ...
     ZES_ENABLE_SYSMAN: '1'
 }

console.log( process.uptime() ); // 실행에 걸린 시간. // (메소드이므로 소괄호가 있음.)
 // 0.0313737 

console.log( process.cwd() );  // 현재 동작중인 위치. // C:\yjcho\Node.js\day2

console.log( process.cpuUsage() ); 
// 파일의 용량.(user에서 사용할 때의 용량과 system에서 사용할 때의 용량이 다름) // { user: 46000, system: 0 }


setTimeout(() => {
    console.log('setTimeout');
}, 0); // 0:밀리초. 막바로 실행. // 위에 있는 9개의 console.log()가 모두 차례대로 실행되고 나서야 실행됨.

process.nextTick(()=>{
    console.log('nextTick:');
}) // callback에 우선순위를 갖게 해주는 메소드.
// setTimeout()이 먼저 등록이 되어있더라도, nextTick()이 stack에 먼저 올라가게 됨.

for(let i=0; i<1000; i++){
    console.log('for loop:', i);
}

 

9. timer

setTimeout ( '실행할함수' , '지연할시간(밀리초)'

지정된 시간 후에 한 번만 실행되는 함수를 호출.


setInterval ( '실행할함수' , '반복간격(밀리초)' ) 

일정한 시간 간격으로 반복적으로 실행되는 함수를 호출하여 타이머를 조작.

 

clearInterval ( '타이머' )

setInterval() 함수로 설정한 타이머를 취소.

 

setImmediate ( '실행할함수' )

다른 콜백 함수들이 처리되기 전에 즉시 실행되는 함수를 등록하기 위해 사용.
setTimeout() 함수와 달리  I/O 이벤트 처리가 완료된 후에 실행되는 콜백 함수를 지정.

일반적으로 setTimeout() 함수와 동일한 속도로 출력.

 

nextTick ( '실행할함수' )

현재 실행 중인 함수가 종료된 후, 콜백 함수를 호출하기 위해 사용.

이 함수는 일반적으로 동기식으로 처리하고자 할 때 사용.

 


let num = 1;
const interval = setInterval(()=>{                     // interval이라는 변수로 setInterval()함수 실행.
    console.log(num++); 
}, 1000);                                                           // 1초에 1씩 증가. 멈추고 싶다면 Ctrl+C.


setTimeout(()=>{                                             // 5초 후 Timeout을 출력하여 멈추는 함수 생성.
    console.log('Timeout');
    clearInterval(interval);
}, 5000); 

 


console.log('code1');
setTimeout(() => {
    console.log('setTimeout 0');
    console.timeEnd('timeout 0'); // 0.8ms 후에 출력
}, 0);


console.log('code2');
// 등록된 callback함수를 실행해주는 함수.
setImmediate(()=>{
    console.log('setImmediate');
});


console.log('code3');
process.nextTick(()=>{
    console.log('process.nextTick');
}); // const process=require('process'); 의 생략이 가능. 
// code3 → code1 → code2 순으로 출력됨. 
// code1과 code2는 동일하기 때문에 출력순서에 따라 정해짐.

 

10. path

파일 경로와 관련된 유틸리티 함수를 제공하는 내장 모듈.

파일 경로를 처리하는 데 유용한 기능을 간단하게 구현함.

 

path의 형태
LINUX, Mac: 'users/temp/5-path.js' (POSIX의 주소형태)
Windows: c:\\temp\\5-path.js

 

path 변수를 지정하여 path 모듈을 불러옴.


constpath require('path');

 

path모듈에서의 출력

console.log(__dirname); // 디렉토리의 경로 출력.
console.log(__filename); // 디렉토리의 경로와 파일명까지 출력.


console.log(path.sep); // 각 디렉토리의 구분자 출력.
console.log(path.delimiter); // \, ; // 구분 기호 출력.


console.log(path.basename(__filename)); // 파일명만 출력.
console.log(path.basename(__filename, '.js')); // 확장자를 뺀 파일명만 출력.


console.log(path.dirname(__filename)); // 파일명이 위치한 디렉토리명 출력.
console.log(path.extname(__filename)); // 파일의 확장자만 출력.

 

파일명을 객체로 저장.


const parsed = path.parse(__filename); 
console.log(parsed );
console.log(parsed .root); // 해당 parsed의 절대경로 출력. // C:\ 출력

 

 경로를 문자열로 변환.


const str = path.format(parsed);
console.log(str);

 

절대경로/상대경로 확인


console.log('isAbsolute: ', path.isAbsolute(__dirname)); // isAbsolute:  true 출력.
console.log('isAbsolute: ', path.isAbsolute('../')); // isAbsolute:  false 출력.

 

오류 수정


console.log(path.normalize('./nodejs////sub/')); // 오류가 있는 경로를 수정해서 출력.

 

경로의 결합 (두개 중 하나를 사용)


// 1번
console.log(__dirname + path.sep + 'image');

// 2번
console.log(path.join(__dirname, './image'));

 

11. file

파일을 다루는 데 사용되는 유틸리티 함수를 제공하는 내장 모듈.

이 모듈을 사용하면 파일을 생성, 수정, 삭제, 읽기 등의 작업을 수행할 수 있음.

 

fs 변수를 지정하여 fs모듈을 불러옴.


const { errorMonitor } = require('events');
const fs require('fs');

 

renameSync()

비동기가 아닌, 동기적으로 움직이는 메소드. (파일 이름이 변경되어야 다음으로 넘어갈 수 있음.)

동기적으로 움직이는 메소드는 오류판별이 쉽지 않기 때문에 ' try { } catch { } 형식 '으로 묶어주는 것이 좋음.

동기식이라 잘 사용되지 않음.


  try { renameSync(...) } catch(e) {   }

try {
    fs.renameSync('./test.txt', './test-new.txt'); // 파일의 이름을 변경.
} catch(e) {
    console.error(e); // test.txt에서 test-new.txt로 바뀜.
}


rename()

file이름을 바꾸어주는 메소드. 비동기적 메소드.

실패했다면 error출력.


rename(..., callback(error)) 

fs.rename('./test-new.txt', './test-new-new.txt', (error)=>{
    console.log(error);
});                                                        //error만 받도록 작성.
console.log('파일 이름 바꾸기');

renameSync()가 먼저 실행이 되었으나, test.txt가 없기 때문에 null이 먼저 출력.
이후 rename()이 실행되어 파일명이 test-new.txt에서 test-new-new.txt로 변경됨.

 

promises.rename(...)

     .then()

     .catch()

 

promises 객체에 rename() 메서드를 실행하고, error발생 시 catch() 메서드를 실행.

 

예) fs.promises.rename()을 사용하여 test-new-new.txt를 test.txt로 변경.

      변경되었다면 'Done!' 출력, error시 'error' 객체를 출력.


fs.promises.rename('./test-new-new.txt', './test.txt')
    .then(()=> console.log('Done!'))
    .catch(console.error);

 

12. buffer

버퍼(buffer)
메모리에 저장되는 일부 공간.
byte단위로 저장되며, integer형태의 배열.

fs 모듈을 사용.


const fsrequire('fs');


const buf = Buffer.from('Hi');
console.log(buf);             //  </buffer 48 69>  //  16진수로 저장된 아스키코드의 형태 출력.
console.log(buf.length);  // 2 // 버퍼의 길이 출력.
console.log(buf[0]);         // 72 (16진수가 아닌 10진수로 저장)
console.log(buf[1]);         // 105 (16진수가 아닌 10진수로 저장)

console.log(buf.toString()); // buf=Hi // 문자열로 변환.

const buf2 = Buffer.alloc(2); // buffer에 2자리를 할당.

buf2[0] = 72;
buf2[1] = 105;

console.log(buf2.toString()); // buf2=Hi


예) 'nodejs'라는 단어를 메모리의 버퍼에 저장하고 출력한 후 변수명을 'buf3'로 저장


// 해당 10진수는 'nodejs'를 16진수의 아스키코드 형태로 출력한 후 각 자릿수(5자리)에 따라 찾는 작업이 선행되어야 함.

const buf3 = Buffer.alloc(6);      // buf3에 6자리를 할당.
buf3[0] = 110;                        
buf3[1] = 111;
buf3[2] = 100;
buf3[3] = 101;
buf3[4] = 106;
buf3[5] = 115;

console.log(buf3.toString());       // buf3=nodejs


concat 사용으로 Buffer끼리 연결이 가능.


const newBuf = Buffer.concat([buf, buf2, buf3]);   // 위의 buf, buf2, buf3을 결합
console.log(newBuf.toString());                             // HiHinodejs 출력.

 

13. stream

연속적으로 발생하는 데이터의 처리방식.

데이터를 '읽기 가능한(readable)' 소스에서 가져와 '쓰기 가능한(writable)' 대상으로 전달.

이 과정에서 중간 처리를 할 수 있으며, 데이터를 조각으로 나누어 전송하거나 병렬 처리를 할 수도 있음.

파일, 네트워크 소켓, HTTP 요청 등 다양한 데이터 소스와 대상에 대해 stream을 사용할 수 있음.

파일 시스템에서 파일을 읽고 쓸 때, 전체 파일을 메모리에 로드하지 않고도 데이터를 처리할 수 있음.

메모리 사용량을 최소화하고 처리 속도를 향상시키는 등의 이점을 제공함.

Node.js에서는 stream API를 통해 쉽게 다룰 수 있음.

fs 모듈을 사용.


const fsrequire('fs');

 

memoryUsage()

현재 프로세스가 사용하는 메모리에 대한 다양한 정보를 객체로 반환.

 

readFile ('경로', ['인코딩방식',] 'callback함수(error객체, data)')

파일 시스템에서 파일을 읽어들임.

파일을 읽는 동안 프로그램의 실행 흐름이 차단되지 않으며(비동기적), callback함수를 호출하여 결과를 반환.

callback함수에서 첫번째 매개변수 error객체와 두번째 매개변수 data 생략은 모두 불가능함.

 

writeFile ('경로', '데이터', ['인코딩방식',] 'callback함수(error객체, data)')

파일 시스템에서 파일을 씀.

파일을 쓰는 동안 프로그램의 실행 흐름이 차단되지 않음.(비동기적)

callback함수에서 첫번째 매개변수 error객체의 생략은 불가능하나 두번째 매개변수 data의 생략은 가능함.


 RSS(Resident Set Size):
 주기억장치에 상주하는 메모리.
 아래 예시에서는 '메모리의 사용량'에 대한 정보.

 

예) test.txt를 읽어들인 후 test2.txt로 data를 복사하는 동안 사용된 메모리의 크기 구하기.


const beforeMem = process.memoryUsage().rss;
// process 객체를 사용하여 현재 프로세스가 사용하는 메모리 사용량(RSS)을 가져와 beforeMem 변수에 할당.

console.log(beforeMem); // 29786112 // 현재 이 컴퓨터가 사용중인 메모리의 크기
// 현재 디렉토리의 file.txt 파일을 읽어옴. 파일을 읽어오는 작업은 비동기적으로 수행.
fs.readFile('./file.txt', (_, data) => {          // readFile()이므로 error 객체의 생략이 불가 → 언더바 콤마(_,)를 사용.
// callback함수의 첫번째 매개변수인 err는 생략할 수 없음. 

    fs.writeFile('./file2.txt', data, () => { }); // 현재 디렉토리에 file2.txt 파일을 생성하고, 첫 번째 인자로 전달된 data를 파일에 씀.

 const afterMem = process.memoryUsage().rss;
 // 파일 쓰기 작업을 수행한 후에 현재 프로세스가 사용하는 메모리 사용량(RSS)을 가져와 afterMem 변수에 할당.

 const diff = afterMem - beforeMem;
 const consumed = diff / 1024 / 1024; // MB 형식으로 변경.
 console.log(diff); // 724992 // data의 차이
 console.log(`Consumed Memory: ${consumed}MB`); 
});   // Consumed Memory: 0.69140625MB 

 

createReadStream('경로', ['옵션'])

파일의 내용을 stream 형태로 읽을 때 사용.

옵션:

highWaterMark

스트림에서 한 번에 읽거나 쓸 수 있는 데이터의 양을 제어하는 옵션.

한 번에 처리할 수 있는 데이터의 크기를 제한. (기본 64byte에서 8byte로 제한.)

 

const readStream = fs.createReadStream('./file.txt', {
    highWaterMark: 8,
    encoding: 'utf-8'
});

const beforeMem = process.memoryUsage().rss;
const data = [ ];

readStream .on('data', (chunk) => {       // data를 chunk(덩어리)로 가져왔다는 의미의 chunck 변수 사용.
    console.log(chunk);
    console.count('data'); // data: 1
    readStream .close();   // stream을 종료.
});
// </buffer 4c 6f 72 65 6d 20 69 70 73 75 6d 20 64 6f 6c 6f 72 20 73 69 74 2c 20 61 6d 65 74 20 63 6f 6e 73 65 63 74 65 74 75 72 20 61 64 69 70 69 73 69 63 69 6e ... 23024 more bytes>
// highWaterMark와 encoding을 추가했을 때 //  data: 2885 (2885번 8byte씩 쪼개서 출력됨)

readStream
.on('close', () => {                                // readStream의 close 시 해당 함수를 callback.

const afterMem = process.memoryUsage().rss;

const diff = afterMem - beforeMem ;
const consumed = diff / 1024 / 1024;
console.log(diff);        // 450560
console.log(`Consumed Memory: ${consumed}MB`); // Consumed Memory: 0.4296875MB
})

 

14. pipe

스트림 간에 데이터를 전송.

스트림을 연결하여 데이터의 흐름을 자동으로 처리할 수 있도록 해주는 기능을 제공.

fs, zlib 모듈을 사용.


const fsrequire('fs');
const zlib = require('zlib');

 

zlib.createGzip(['옵션'])

데이터를 Gzip 압축 형식으로 압축하기 위한 스트림 객체를 생성. zlib 모듈에 포함.

 

fs.createWriteStream('경로', ['옵션'])

쓰기 가능한 스트림 객체를 생성. fs모듈을 불러옴.

 


const readStream = fs.createReadStream('./file.txt'); // file.txt 파일을 읽기용 스트림 객체로 생성.
const zlibStream = zlib.createGzip();                         // gzip 압축을 수행하는 스트림 객체를 생성.
const writestream = fs.createWriteStream('./file3.txt');

const piping = readStream .pipe(zlibStream ).pipe(writestream );
// readStream에서 읽은 데이터가 zlibStream을 통해 압축되어 writeStream으로 전달 → 읽고, 압축해서, 내보내겠다는 의미.

piping .on('finish', () => {                          // piping이 finish라면, Done을 출력.
    console.log('Done');
})