4챕터
노드의 기본 기능 알아보기 이다.
이 챕터에서는 서버를 만들기 전에 알아야 할 기본 내용을 다루고 있다.
주소 문자열과 요청 파라미터 다루기
url 모듈을 사용하여 일반 주소 문자열을 URL객채로 만들거나 URL객체서 일반 문자열로 변환하는 것을 쉽게 할 수 있다.
URL객체의 속성 중 query속성은 요청 파라미터의 정보를 가지고 있다. 요청 파라미터는 & 기호로 구분되는데 querystring모듈을 통해 쉽게 분리할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
/*
주소 문자열
*/
var url = require('url');
//주소 문자열을 URL 객체로 만들기
//parse(): 주소 문자열으 ㄹ파싱하여 URL 객체로 만들어준다.
var curURL = url.parse('https://www.google.co.kr/search?q=%E3%85%8E&oq=%E3%85%8E&aqs=chrome..69i57j69i61l3j0l2.1980j0j7&sourceid=chrome&ie=UTF-8');
//URL 객체를 주소 문자열로 만들기
//format(): URL객체를 주소 문자열로 반환한다.
var curStr = url.format(curURL);
console.log('주소 문자열: %s', curStr);
console.dir(curURL);
/*
요청 파라미터 확인하기
*/
var querystring = require('querystring');
var param = querystring.parse(curURL.query);
console.log('요청 파라미터 중 query의 값: %s', param.query);
//stringify() : 요청 파라미터 객체를 문자열로
console.log('원본 요청 파라미터 : %s', querystring.stringify(param));
| cs |
이벤트
노드는 대부분 이벤트를 기반으로 하는 비동기 방식으로 처리한다. 그리고 비동기 방식으로 처리하기 위해서는 서로 이벤트를 전달한다. 이벤트는 한쪽에서 다른 쪽으로 알림 메시지를 보내는 것과 비슷하다. 노드는 이런 이벤트를 보내고 받을 수 있도록 EventEmitter라는 것을 만들었다.
노드의 객체는 EventEmitter를 상속받을 수 있으며, 상송 받은 후에는 EventEmitter 객체의 on()과 emit()메소드를 사용할 수 있다.
EventEmitter의 주요 메소드이다
on(event, listener): 지정한 이벤트의 리스터를 추가한다.
once(event, listener): 지정한 이벤트의 리스터를 추가하지만 한 번 실행한 후에는 자동으로 리스너가 제거된다.
removeListener(event, listener): 지정한 이벤트에 대한 리스너를 제거한다.
노드의 객체는 EventEmitter를 상속받을 수 있으며, 상송 받은 후에는 EventEmitter 객체의 on()과 emit()메소드를 사용할 수 있다.
EventEmitter의 주요 메소드이다
on(event, listener): 지정한 이벤트의 리스터를 추가한다.
once(event, listener): 지정한 이벤트의 리스터를 추가하지만 한 번 실행한 후에는 자동으로 리스너가 제거된다.
removeListener(event, listener): 지정한 이벤트에 대한 리스너를 제거한다.
1
2
3
4
5
6
7
8
9
10
11
|
process.on('tick', function(count){
console.log('tick 이벤트 발생함 : %s ', count);
});
//setTimeout을 이용하여 2초 후에 동작 설정
setTimeout(function(){
console.log('2초 후에 tick 이벤트 전달 시도');
//emit를 이용해 tick이벤트를 process객체로 전달
process.emit('tick', '2');
},2000);
| cs |
파일 다루기
노드는 동기식 IO와 비동기식 IO 기능을 함께 제공한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
/*
동기식 읽기
*/
var fs = require('fs');
//readFileSync: 동기식 파일 읽기
var data = fs.readFileSync('./package.json', 'utf-8');
console.log(data);
/*
비동기식 읽기
*/
//raedFile 메소드를 실행하면서 세번째 파라미터로 전달된 함수는 파일을 읽어들이는 작업이 끝났을때 호출됨
//이때, 2개의 파라미터 err와 data를 전달 받아 오류가 발생했는지 아니면 제대로 실행했는지 알 수 있음
fs.readFile('./package.json','utf-8', function(err, data2){
console.log(data2);
});
console.log('package 파일을 읽도록 요청');
/*
파일에 데이터 쓰기 예제
*/
fs.writeFile('./output.txt', 'Hello', function(err){
if(err){
console.log('Error: ' + err);
}
console.log('output.txt 쓰기 완료');
})
| cs |
버퍼
버퍼 객체는 바이너리 데이터를 읽고 쓰는데 사용한다. new연산자를 사용해 새로운 바퍼 개체를 만들 수 있으며, 바이트 데이터 크기만 지정해주면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
/*
버퍼*/
//버퍼 객체를 크기만 지정하여 만든 후 문자열 작성
var output = '안녕1';
var buffer1= new Buffer(10);
var len = buffer1.write(output, 'utf8');
console.log('첫 번째 버퍼의 문자열: %s', buffer1.toString());
//버퍼 객체를 문자열을 이용해 만들기
var buffer2 = new Buffer('안녕2', 'utf8');
console.log('두 번째 버퍼 객체의 문자열: %s', buffer2.toString());
//타입 확인
console.log('버퍼 객체의 타입: %s', Buffer.isBuffer(buffer1));
//버퍼 객체에 들어 있는 문자열 데이터를 문자열 변수로 만들기
var byteLen = Buffer.byteLength(output);
var str1 = buffer1.toString('utf8', 0, byteLen);
var str2 = buffer2.toString('utf8');
//첫 번째 버퍼 객체의 문자열을 두 번째 버퍼 객체로 복사
buffer1.copy(buffer2, 0,0 , len);
console.log('두 번째 버퍼에 복한 후의 문자열: %s', buffer2.toString('utf8'));
//두 개의 버퍼 붙이기
var buffer3 = Buffer.concat([buffer1,buffer2]);
console.log('두 개의 버퍼를 붙인 후의 문자열: %s', buffer3.toString('utf8'));
| cs |
스트림 단위로 파일 읽고 쓰기
파일을 읽거나 쓸 때는 데이터 단위가 아닌 스트림 단위로 처리할 수 있다. 스트림은 데이터가 전달되는 통로와 같은 개념..?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
var fs = require('fs');
//createReadStream(path[,options]) - 파일을 읽기 위한 스트림 객체 만들기
var infile = fs.createReadStream('./output.txt', {flags:'r'});
//createWriteStream(path[,options]) - 파일을 쓰기 위한 스트림 객체 만들기
var outfile = fs.createWriteStream('./output2.txt', {flags:'w'});
infile.on('data', function(data){
console.log('읽어 들인 데이터', data);
outfile.write(data);
});
infile.on('end', function(){
console.log('파일 읽기 종료');
outfile.end(function(){
console.log('파일 쓰기 종료');
});
});
var outfile2 = fs.createWriteStream('./output3.txt',{flags:'w'});
//pipe를 이용해 두 개의 스트림을 붙일 수 있다.
infile.pipe(outfile2);
console.log('파일복사 방법2')
| cs |
fs모듈로 디렉터리 만들기
1
2
3
4
5
6
7
8
9
10
11
|
var fs = require('fs');
fs.mkdir('./docs', 0666, function(err){
if(err) throw err;
console.log('새로운 docs 폴더를 만들었습니다.');
fs.rmdir('./docs', function(err){
if(err) throw err;
console.log('docs 폴더를 삭제했습니다.');
});
});
| cs |
로그 파일 남기기
프로그램의 크기가 커질 수록 로그의 양도 많아지고 로그를 보고간했다가 나중에 확인해야하는 경우도 생긴다.
책에선 winston 모듈을 사용한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
var winston = require('winston'); // 로그 처리 모듈
var winstonDaily = require('winston-daily-rotate-file'); // 로그 일별 처리 모듈
var moment = require('moment'); // 시간 처리 모듈
function timeStampFormat() {
return moment().format('YYYY-MM-DD HH:mm:ss.SSS ZZ');
};
var logger = new (winston.Logger)({
transports: [
new (winstonDaily)({
name: 'info-file',
filename: './log/server',
datePattern: '_yyyy-MM-dd.log',
colorize: false,
maxsize: 50000000,
maxFiles: 1000,
level: 'info',
showLevel: true,
json: false,
timestamp: timeStampFormat
}),
new (winston.transports.Console)({
name: 'debug-console',
colorize: true,
level: 'debug',
showLevel: true,
json: false,
timestamp: timeStampFormat
})
],
exceptionHandlers: [
new (winstonDaily)({
name: 'exception-file',
filename: './log/exception',
datePattern: '_yyyy-MM-dd.log',
colorize: false,
maxsize: 50000000,
maxFiles: 1000,
level: 'error',
showLevel: true,
json: false,
timestamp: timeStampFormat
}),
new (winston.transports.Console)({
name: 'exception-console',
colorize: true,
level: 'debug',
showLevel: true,
json: false,
timestamp: timeStampFormat
})
]
});
//로그 테스트
var fs = require('fs');
var inname = './output.txt';
var outname = './output2.txt';
fs.exists(outname, function (exists) {
if (exists) {
fs.unlink(outname, function (err) {
if (err) throw err;
logger.info('기존 파일 [' + outname +'] 삭제함.');
});
}
var infile = fs.createReadStream(inname, {flags: 'r'} );
var outfile = fs.createWriteStream(outname, {flags: 'w'});
infile.pipe(outfile);
logger.info('파일 복사 [' + inname + '] -> [' + outname + ']');
});
| cs |
댓글 없음:
댓글 쓰기