티스토리 뷰

  • 파일 다루기

1. 노드의 파일 시스템은 파일을 다루는 기능, 디렉터리를 다루는 기능으로 구성되어 있다. 또한, 동기식 I/O(Input output), 비동기식 I/O 기능을 함께 제공한다.

2. 동기식 IO 는 파일 작업이 끝날 때까지 대기하며, 비 동기식 IO는 파일작업을 요청하고 그 다음 작업을 바로 수행한다. 이후 파일 작업이 끝나면 그 상태는 이벤트로 받아서 처리한다. 동기식 IO와 비동기식 IO를 구별하기 위해 동기식 IO 메소드는 Sync라는 단어를 붙인다.
(동기식 IO가 더 느리다. 대기하므로)
  • 파일을 읽어 들이거나 파일에 쓰기
동기적
// 파일을 동기식 IO로 읽어 들인다.

var fs = require('fs');        
 // 파일 시스템에 접근 하기 위해 fs 모듈 사용
var data = fs.readFileSync('./package.json','utf-8');     
  // readFileSync 이므로 동기식 동작
console.log(data);        
  // 파일을 다 읽을때 까지 실행 되지 않는다. why? 동기식이므로 모든 동작이 끝나야함.
{
"name": "server_side_javascript",
"version": "1.0.0",
"description": "server side javascript tutorials",
"main": "module.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"body": "^5.1.0",
"express": "^4.15.4",
"jade": "^1.11.0",
"underscore": "^1.8.3"
}
}

비동기적

var fs = require('fs');       
// 파일 시스템에 접근 하기 위해 fs 모듈 사용
fs.readFile('./package.json','utf-8',function(err,data){
// readFile 이므로 비 동기식이며, readFile()메소드를 실행하면서 세번쨰 파라미터로 전달된 함수는 파일을 읽어들이는 작업이 끝났을때 호출이 된다. 이때, err,data 를 전달받아 오류 발생여부 확인할 수 있다.
    console.log(data);             
  //에러 발생시 err은 오류 데이터가 들어가고 에러 발생하지 않았을 경우 null 값이 들어간다.
});
console.log('프로젝트 폴더 안의 package.json file Read require');       
// readFile메소드를 먼저 호출했지만, 출력이 먼저나온다 why? 비동기적 동작을 하였기 때문에.

{
"name": "server_side_javascript",
"version": "1.0.0",
"description": "server side javascript tutorials",
"main": "module.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"body": "^5.1.0",
"express": "^4.15.4",
"jade": "^1.11.0",
"underscore": "^1.8.3"
}
}

  • 파일을 읽고 쓰는 대표적인 네가지 메소드

메소드 이름 

설명 

readFile(filename,[encoding],[callback] 

비동기식 IO로 파일을 읽어 들인다. 

 readFileSync(filename,[encoding])

동기식 IO로 파일을 읽어 들인다.

writeFile(filename,data,encoding='utf',[callback])

비동기식 IO로 파일을 쓴다. 

 writeFileSync(filename,data,

encoding='utf8')


동기식 IO로 파일을 쓴다. 


=> 대부분은 비동기 방식으로 파일을 읽고 쓰기 때문에 비동기 방식의 메소드를 주로 사용한다.

fs 모듈 (file System)
1. 비동기식 IO
readFile,writeFile
2. 동기식 IO
readFileSync,writeFileSync

  • 파일에 데이터를 쓰는 예제
var fs = require('fs');
fs.writeFile('./output.txt', 'hello world!',function(err){      
// writeFile()메소드는 1파라미터: 파일이름 2파라미터: 파일에 쓸 내용 3파라미터: 콜백 함수 
    
   if(err){
       console.log('Error' + err);
   } 
    
    console.log('output.txt 파일에 데이터 쓰기 완료');
});
output.txt 파일에 데이터 쓰기 완료


=> output.txt 파일에 글자가 쓰여진것을 알수 있다.
  • 파일을 직접 열고 닫으면서 읽거나 쓰기

메소드 이름

설명 

 open(path,flags,[mode]

,[callback])

파일을 엽니다. 

 read(fd,buffer,offset,length

,positon,[callback])

지정한 부분의 파일 내용을 읽어 들입니다. 

 write(fd,buffer,offset,length

,position,[callback])

파일의 지정한 부분에 데이터를 씁니다. 

close(fd,[callback])

파일을 닫아준다. 




  • 파일 열고 데이터 쓰고 파일 닫기 예제
var fs = require('fs');
// fs 모듈 가져옴

//파일 열기
fs.open('./output.txt','w',function(err,fd){
    if(err) throw err;
    // 버퍼 객체 생성.
    var buf = new Buffer('안녕!\n');
// 파일 쓰기    fs.write(fd,buf,0,buf.length,null,function(err,written,buffer){
        if(err) throw err;
            console.log(err,written,buffer);
        // 파일 닫기
        fs.close(fd,function(){
            console.log('파일 열고 데이터 쓰고 파일 닫기 완료')
        })
    })
})

null 8
파일 열고 데이터 쓰고 파일 닫기 완료
=> 코드 설명 : 'w' 플래그를 사용하였으므로, 쓰기 작업만을 위해 파일을 연다. 콜백 함수 안에는 버퍼 객체를 하나 만든다. 그 이후 write() 메소드를 호출 하여 파일에 내용을 쓴다. 파일이 열리면 fd 객체를 전달 받을 수 있으므로 이 fd 객체로 파일을 구별한다. 파일에 데이터를 쓸때 어느 위치에 쓸 것인지 정할 수 있다. 

함수 호출 순서 = 'open -> write -> close'

open() 메소드 호출 하면 파일 열수 있다. 그리고 파일을 열면 write()메소드를 사용해서 데이터를 쓸 수 있다. 데이터는 필요한 만큼 Buffer 객체 안에 쓴다. 파일에 데이터를 쓰고 나면 close() 메소드를 호출하여 파일을 닫습니다.
이렇게 각 메소드를 호출 할 때 마다 콜백 함수를 파라미터로 전달 하므로 각각의 기능이 실행을 끝냈을 때 그 다음메소드를 전달한다. 


  • 대표적인 플래그 

플래그 

설명 

 'r'

읽기에 사용하는 플래그 파일이 없으면 예외 발생 

'w' 

쓰기에 사용하는 플래그 파일이 없으면 만들어 지고 파일이 있으면 이전내용을 모두 삭제한다 

 'w+'

읽기와 쓰기에 모두 사용하는 플래그. 파일이 없으면 만들어 지고 파일이 있으면 이전 내용을 모두 삭제 한다 

 'a+'

읽기와 추가에 모두 사용하는 플래그 파일이 없으면 만들어지고 있으면 이전 내용에 새로운 내용을 추가 한다. 



  • 위의 예제를 통해 만들어진 파일을 읽어 들여 볼까요?
var fs = require('fs');

fs.open('./output.txt','r',function(err,fd){
    if(err) throw err;
    
    var buf = new Buffer(10);
// Buffer 객체는 바이너리 데이터를 읽고 쓰는데 사용한다. 새로운 버퍼 객체를 만들기 위해서는 new 연산자 사용하며, 그 안에 들어갈 바이트(byte) 데이터의 크기만 지정하면 된다.
write() 메소드를 사용해 문자열-> 버퍼에 쓰거나, 처음부터 문자열을 -> 버퍼객체를 만들수 있다.

    console.log('버퍼 타입 : %s',Buffer.isBuffer(buf));
    
// 파일 읽기
    fs.read(fd, buf, 0, buf.length, null, function(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('output.txt 파일을 열고 읽기 완료');
        })
        
        
    })
})
버퍼 타입 : true
파일에서 읽어온 데이터 : 안녕!
null 8
output.txt 파일을 열고 읽기 완료

  • 버퍼 객체 사용하는 방법 알아보기


// 1.버퍼 객체를 크기만 지정하여 만든 후 문자열을 씁니다.
var output = '안녕 1!';
var buffer1 = new Buffer(10);
var len = buffer1.write(output, 'utf8');
console.log('첫번째 버퍼의 문자열 : %s', buffer1.toString());

// 2.버퍼 객체를 문자열을 이용해 만듭니다.
var buffer2 = new Buffer('안녕 2!', 'utf8');
console.log('두번째 버퍼의 문자열 : %s', buffer2.toString());
=> 두개의 버퍼를 서로 다른 방식으로 만든다.
1. 빈버퍼 먼저 만들고 그안에 문자열 넣기 
2. 버퍼를 만들면서 문자열을 파라미터로 전달

// 타입을 확인합니다. isBuffer() 메소드로 확인
console.log('버퍼 객체의 타입 : %s', Buffer.isBuffer(buffer1));
// 버퍼 객체에 들어있는 문자열 데이터를 문자열 변수로 만듭니다.
var byteLen = Buffer.byteLength(output);
var str1 = buffer1.toString('utf8', 0, byteLen);
var str2 = buffer2.toString('utf8');

// 두번째 버퍼 객체의 문자열을 첫 번째 버퍼 객체로 복사합니다. copy() 메소드 사용
buffer1.copy(buffer2, 0, 0, len);
console.log('두번째 버퍼에 복사한 후의 문자열 : %s', buffer2.toString('utf8'));

// 두 개의 버퍼를 붙여줍니다. 두개의 버퍼를 붙여서 새로운 버퍼 객체를 만들 때 
var buffer3 = Buffer.concat([buffer1, buffer2]);
console.log('두 개의 버퍼를 붙인 후의 문자열 : %s', buffer3.toString('utf8'));

첫번째 버퍼의 문자열 : 안녕 1!
두번째 버퍼의 문자열 : 안녕 2!
버퍼 객체의 타입 : true
두번째 버퍼에 복사한 후의 문자열 : 안녕 1!
두 개의 버퍼를 붙인 후의 문자열 : 안녕 1! 안녕 1!

  • 스트림 단위로 파일 읽고 쓰기
1. 파일을 읽거나 쓸 때는 데이터 단위가 아닌 스트림 단위로 처리 할 수 있다.
2. 스트림은 데이터가 전달되는 통로
3. 버퍼는 임시 저장소
4. 파일을  읽을 때는 createReadStream(), 파일을 쓸때는 createWriteStream() 메소드로 스트림 객체를 만든 후 데이터를 읽고 쓰게 된다.


메소드 이름 

설명 

 createReadStream(path,[options])

파일을 읽기 위한 스트림 객체를 만든다. 

 createWriteStream(path,[options])

파일을 쓰기 위한 스트림 객체를 만든다. 



Example) output.txt파일 읽어 들인후 -> output2.txt 파일로 쓰는 예제


// 스트림 단위로 파일 읽고 쓰기


var fs = require('fs');


var infile = fs.createReadStream('./output.txt',{falgs : 'r'});

var outfile = fs.createWriteStream('./output2.txt',{flags :'w'});


// Stream 이벤트 등록

infile.on('data',function(data){

    console.log('읽어 들인 데이터',data);

    outfile.write(data);

});

// Stream 이벤트 등록

infile.on('end',function(){

    

    console.log('파일 읽기 종료');

    outfile.end(function(){

        console.log('파일 쓰기 종료');

        

    })

    

})

읽어 들인 데이터
파일 읽기 종료

파일 쓰기 종료

  • 위의 예제를 두 개의 스트림을 붙여 주면 더 간단하게 만드는 것을 알아볼까요?



var fs = require('fs');
var inname = './output.txt';
var outname = './output2.txt';


// outname의 파일을 모두 삭제 하기 위함.
fs.exists(outname, function(err){
    if(err){
        fs.unlink(outname,function(err){                // link를 끊어 버리기 위해 unlink(파일 삭제를 의미한다.)
            if(err) throw err;
            console.log('기존 파일 [' + outname +']삭제함');
        })
    }
})
// infile 과 outfile 변수에 스트림을 쓴다. 
var infile = fs.createReadStream(inname,{flags:'r'});
var outfile = fs.createWriteStream(outname,{flags : 'w'});
infile.pipe(outfile); // infile 스트림과 outfile 스트림을 객체를 연결하기 위한 pipe() => 파일 내용 복사
console.log('파일 복사 [ ' + inname + '] -> ' + outname + ']');

파일 복사 [ ./output.txt] -> ./output2.txt]

  • http 모듈로 요청받은 파일 내용을 읽고 응답하기
var fs= require('fs');
var http = require('http');
var server = http.createServer(function(req,res){       // 웹 서버에서 클라이언트로 부터 요청을 받으면
    // 파일을 읽어 응답 스트림과 pite로 연결 한다.
    var instream=fs.createReadStream('./output.txt');         // output.txt 스트림을 생성
    instream.pipe(res);         // output.txt 스트림과 응답 res 를 연결 한다 pipe() 메소드로 pipe() 메소드는 연결할 수 있다는것만 이해하면 된다.
    // 쉽게 말해서 output.txt 파일의 통로가 열리게 되면서 pipe에 의해  요청된 파일의 응답을 할수 있게 된다.  pipe() 메소드는 읽기 스트림과 쓰기 스트림을 연결 시킨다.
});
server.listen(7001,'127.0.0.1');
  • fs 모듈로 새 디렉터리 만들고 삭제 하기
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 폴더가 삭제 되었습니다.")
             
     })
})


공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
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
글 보관함