[Node.js] 파일 처리하기 - 버퍼, http 모듈, 디렉터리

파일 읽고 쓸 때 버퍼 사용하기

실제로 파일을 읽고 쓸 때는 한꺼번에 모든 데이터를 읽고 쓰지 않고 조금씩 읽고 쓰는 방식을 사용하는 경우도 많다. 또한 다른 곳의 데이터를 파일에 쓰는 경우도 있기 때문에 파일을 다루는 다양한 방식이 정의되어 있다.

open(path, flags, [mode], [callback]): 파일 열기
read(fd, buffer, offset, length, position, [callback]): 지정한 부분의 파일 내용 읽기
write(fd, buffer, offset, length, position, [callback]): 파일의 지정한 부분에 데이터 쓰기
close(fd, [callback]): 파일 닫기

기본적으로 파일 함수를 호출하는 순서는 open - write - close이다.

var fs = require('fs');
fs.open('./output.txt''w'function(err, fd){
    if(err) throw err;
    
    var buf = new Buffer('Hi!\n');
    fs.write(fd, buf, 0, buf.lengthnullfunction(err, written, buffer){
        if(err) throw err;
        
        console.log(err, written, buffer);
        
        fs.close(fd, function(){
            console.log('파일 열기, 쓰기, 닫기 완료');
        });
    });
});
cs

코드를 보면 open 안에 write, write 안에 close가 있음을 알 수 있다. open() 메소드 안의 'w'는 플래그(flag)이다.

대표적인 플래그는 다음과 같다.

r: 읽기 플래그, 파일이 없으면 예외 발생
w: 쓰기 플래그, 파일이 없으면 만들고 있으면 이전 내용 모두 삭제
w+: 읽기/쓰기 플래그, 파일이 없으면 만들고 있으면 이전 내용 모두 삭제
a+: 읽기/추가 플래그, 파일이 없으면 만들고 있으면 이전 내용에 새로운 내용 추가

정상적으로 파일이 open되면 fd 객체로 값을 전달받는다. 그 후 write할 때 buf의 내용을 offset 0부터 buf의 길이만큼 쓴다. 쉽게 말해서 0부터 buf에 쓴 길이만큼 전부 다 쓴다는 말이다. 그리고 close로 파일을 닫는다. buf는 버퍼 객체인데 나중에 설명한다.

open, write, close의 에러 핸들링은 모두 err 인자로 콜백함수 선언에서 가능하다.

이제 이 파일을 읽는 코드를 작성해보자.

var fs = require('fs');
fs.open('./output.txt''r'function(err, fd){
    if(err) throw err;
    
    var buf = new Buffer(10);
    
    fs.read(fd, buf, 0, buf.lengthnullfunction(err, bytesRead, buffer){
        if(err) throw err;
        
        var inStr = buffer.toString('utf8'0, bytesRead);
        console.log('파일에서 읽은 데이터: %s', inStr);
        
        console.log(err, bytesRead, buffer);
        
        fs.close(fd, function(){
            console.log('파일 읽고 열기 완료');
        });
    });
});
cs

위의 write 코드를 이해한다면 read 코드의 이해는 어렵지 않을 것이다.

Buffer 객체는 바이너리 데이터를 읽고 쓰는데 사용한다. 새로운 버퍼 객체를 만들기 위해서는 new 연산자를 사용하며, 그 안에 들어갈 바이트의 크기만 정하면 된다. 빈 버퍼를 먼저 만들고 문자열을 넣어도 되고 버퍼를 만들고 문자열을 전달할 수도 있다.

Buffer 객체에서도 사용할 수 있는 기능이 많다. 타입을 확인할 때 isBuffer(), 문자열 데이터를 문자열 변수로 만들 때 toString(), 한 버퍼의 문자열을 다른 버퍼 객체로 복사할 때 copy(), 두 개의 버퍼를 붙일 때 concat()을 사용할 수 있다.

http 모듈로 파일 읽고 응답하기

스트림을 서로 연결하는 방법을 이용하면 웹 서버를 만들고 사용자의 요청을 처리할 때 유용하다. http 모듈을 사용해서 사용자로부터 요청을 받았을 때 파일의 내용을 읽어 응답으로 보내는 코드를 작성해보자.

var fs = require('fs');
var http = require('http');
var server = http.createServer(function(req, res){
    var instream = fs.creadReadStream('./output.txt');
    instream.pipe(res);
});
server.listen(7001'127.0.0.1');
cs

웹 서버에서 요청을 받으면 output.txt 파일에서 스트림을 만든 후 클라이언트로 데이터를 보낼 수 있는 스트림과 pipe를 사용해 연결해준다. 두 객체의 연결이 가능한 이유는 파일에서 데이터를 읽기 위해 만든 것도 스트림 객체이고, 데이터를 쓰기 위해 웹 서버에서 클라이언트쪽에 만든 것도 스트림 객체이기 때문이다.

새 디렉터리 생성, 삭제

fs 모듈에는 디렉터리에 대한 기능도 포함되어 있다.

var fs = require('fs');
 
fs.mkdir('./docs'0666function(err){
    if(err) throw err;
    console.log('docs 폴더 생성 완료');
    
    fs.rmdir('./docs'function(err){
        if(err) throw err;
        console.log('docs 폴더 삭제 완료');
    })
})
cs

mkdir로 폴더를 생성하고 rmdir로 폴더를 삭제할 수 있다. 위 코드는 폴더의 생성과 삭제가 한번에 이루어진다.

댓글 없음:

Powered by Blogger.