티스토리 뷰

node.js

6. Node.js에서 파일시스템 접근

채영도 2016. 1. 4. 22:02

Node.js는 fs모듈을 통해서 파일 시스템과 상호 작용을 위한 좋은 인터페이스를 제공한다.

 

fs모듈 - 파일 생성, 읽기, 쓰기, 상호 작용을 위한 표준 파일 접근 API를 포함한다.

 

var fs = require('fs');

require()

To require modules. See the Modules section. require isn't actually a global but rather local to each module.

모듈을 요구하기 위해 사용되며 전역적이 아니라 지역적으로 사용된다.

module

A reference to the current module. In particular module.exports is used for defining what a module exports and makes available through require().

module isn't actually a global but rather local to each module.

단위

 

Node.js의 fs모듈은 거의 모든 기능을 두 가지 형태로 제공

 

동기적 파일 시스템 VS 비동기적 파일 시스템

 

동기적 파일 시스템 호출은 호출이 끝날 때까지 블록 상태를 유지한 후 스레드로 제어가 넘어온다. 이 방식은 동기적 호출이 메인 이벤트 스레드를 블록하거나 너무 많은 백그라운드 스레드 풀의 스레드를 사용할 경우 심각한 성능 저하를 가져올 수 있다.

 

비동기적 호출은 이벤트 큐에 추가된 후 실행된다. 비동기 호출은 자동으로 예외처리를 하고 오류 객체를 첫 전달인자로 전달하는 반면 동기적 호출방식에서는 반드시 try/catch 블록을 사용해 예외처리를 한다. 그리고 동기 호출은 바로 실행되고 수행이 완료될 때까지 제어가 현재 스레드로 반환되지 않는다. 비동기 호출은 이벤트 큐에 위치된 후 제어가 바로 수행 중이던 코드로 반환된다. 실제 파일 시스템 호출은 이벤트 큐에서 선택된 이후 수행된다.

 

쉽게 말해서 동기 호출이란 애플리케이션 프로세스에서 하부작업(프로시저, 함수, 메서드) 요청 시 요청된 하부 작업이 진행되는 동안 호출 프로세스(스레드)의 실행 흐름이 멈추게 되는 호출을 말하고, 멈춘 호출 프로세스(스레드)의 실행 흐름은 하부 작업이 리턴되면 다시 계속된다.

 

비동기 호출은 애플리케이션 프로세스(스레드)에서 하부작업 요청 시 요청된 하부작업의 실행 또는 종료와 관계없이 호출 프로세스(스레드)의 실행 흐름은 계속되는 호출을 말한다. 이런 호출 방식에서는 하부작업의 실행완료 시점을 호출 프로세스(스레드)가 정확히 알지 못하므로 호출 프로세스(스레드)와 하부 작업은 하부작업의 실행 결과를 둘 사이 약속된 결과나 영역 조회, 하부 작업이 호출 프로세스(스레드)를 호출하는 Callback 메커니즘을 통해서 확인할 수 있다.

 

Node.js의 이벤트 처리가 비동기적으로 이루어지므로 fs의 비동기 호출이 Node.js의 이벤트 모델에 적합

싱글스레드 기반의 비동기 io 방식

 

파일 열기 및 닫기

파일이 한 번 열린 후에는 파일을 열 때 사용했던 플래그 값에 맞춰 데이터를 읽고 쓸 수 있다.

fs.open(path, flags, [mode], callback)(비동기식) / fs.openSync(path, flags, [mode])(동기식)

path는 파일 시스템내의 표준 경로

flag는 파일을 열기 위한 모드지정

mode는 선택적인 항목으로 파일 시스템 접근 모드 설정, 기본 설정 값은 0666으로 읽기 쓰기가 가능하다.


간단한 파일 쓰기 예제

var fs = require('fs');
var config = {
maxFile:20,
maxConnection:15,
rootPath: "/webroot"
};

var configTxt = JSON.stringify(config);
var options = {encoding:'utf8', flag:'w'};
fs.writeFile('../data/config.txt', configTxt, options, function(err){
if(err){
console.log("Failed");

}else {
console.log("Success");
}
});

동기적 파일 쓰기

fs.writeSync(fd, data, offset, length, position)을 통해 연속된 문자열 데이터를 파일에 저장할 수 있다.

 

비동기적 파일 쓰기 141p

fs.write(fd, data, offset, length, position, callback)

비동기 방식의 파일 쓰기 함수는 쓰기 요청을 이벤트 큐에 넣은 후 호출한 코드로 제어를 반환한다.

실제 쓰기는 이벤트 큐에서 쓰기 요청이 뽑아져 나와 실행되기 전까지 이뤄지지 않는다. 동일한 파일에 여러 쓰기 요청을 수행할 때는 실행 순서가 보장되지 않기 때문에 주의해야 하며 순서를 맞추기 위해 callback을 사용하여 순서를 맞출 수 있다.

 

여기서 fd는 파일 디스크립터(File Descriptor)로 파일을 관리하기 위해 운영체제가 필요로 하는 파일의 정보를 가지고 있는 것이다. 예를 들어 보조기억장치에서의 파일위치, 파일 구조, 엑세스 제어정도, 파일 유형, 생성 날짜와 시간등이 포함되어 있다. 이것은 openSync()가 반환한 것이다.

offset은 입력 데이터를 읽기 시작할 위치

position은 쓰기를 시작할 파일 내 위치

callback은 error와 bytes를 전달받는 함수를 사용해서 쓰기가 진행된 크기를 지정한다.

 

파일에 비동기적으로 쓰기를 진행하려면 open()을 사용해 파일을 열고 콜백 함수 수행 후에 fs.write()를 사용해 파일에 데이터를 쓴다.

 

비동기 파일 쓰기 형식에서 open()은 파일 디스크립터를 콜백 함수 전달인자로 지정하고, 콜백 함수 내에서 다른 함수를 호출하는데 이런 방식은 비동기 쓰기가 다른 쓰기에 앞서 실행되는 것을 보장할 수 있다.

 

스트리밍 파일 쓰기 143p

대량 데이터를 파일에 쓰기 위해 가장 효율적인 방법 중 하나는 파일을 열어서 writable 스트림으로 사용하는 스트리밍인데 Writable 스트림은 간단히 구현이 가능하고 pipe() 함수를 사용해 Readable 스트림과 간단히 연결 가능하다. 이 방식을 사용해 HTTP 요청과 같은 Readable 스트림 소스에서 매우 간편히 데이터를 쓸 수 있다.

 

fs.createWriteStream(path, [option])

path는 절대 경로나 상대 경로를 사용해 파일의 위치를 지정한다.

option 인자는 encoding과 mode, flag 속성을 지정해 문자열 인코딩과 파일을 열 때 사용하는 모드와 플래그를 설정한다.

 

파일 읽기

 

간단한 파일 읽기 예제

이 함수는 파일 내용 전부를 데이터 버퍼로 읽어 들인다.

var fs = require('fs');
var options = {encoding:'utf8', flag:'r'};
fs.readFile('../data/config.txt', options, function(err, data){
if(err){
console.log("Failed to open Config File");
}else{
console.log("Loaded");
var config = JSON.parse(data);
console.log("Max Files: " + config.maxFile);
console.log("Max Connections: " + config.maxConnection);
console.log("Root Path: " + config.rootPath);
}
});

동기적, 비동기적 파일 쓰기와 마찬가지로 동기적 파일 읽기와 비동기적 파일 읽기가 있다.

 

동기적 파일 읽기

실행중인 스레드로 제어가 반환되기 전에 데이터 읽기를 완료한다. 이때 같은 동작을 여러번 반복할 때는 유리하지만 다른 스레드에서 같은 파일에 접근할 때 원래 읽던 스레드가 끝난 후 접근해야하므로 속도가 느려지게 된다.

 

비동기적 파일 읽기

 

비동기 파일 읽기 방식은 읽기 요청을 이벤트 큐에 넣고 제어를 호출한 코드로 넘겨준다. 이때 실행 순서가 보장되지 않기 때문에 읽기 순서가 중효한 작업에는 주의해야 한다.

실제 읽기 동작은 이벤트 큐에서 해당 요청이 꺼내져 처리될 때까지 미뤄진다.

 

fs.read(fd, buffer, offset, length, position, callback)

buffer는 파일에서 읽는데 사용할 Buffer 객체

offset인자는 데이터를 읽기 시작할 버퍼 위치를 지정

length는 읽을 바이트 수 끝까지 읽으려면 null

 

파일의 경로 검증

경로의 존재 여부를 판별할 때 fs.exists(path, callback) or fs.existsSync(path)

 

파일 삭제

fs.unlink(path, callback)

fs.unlinkSync(path)

 

파일 잘라내기

파일 잘라내기는 파일 끝 위치를 현재보다 작게 만들어 파일 크기를 줄이는 것을 의미한다. 임시로그 데이터와 같이 중요도가 낮은 데이터 파일이 지속적으로 증가되는 경우 파일 잘라내기가 필요하다.

fs.truncate(path, len, callback) - 비동기

fs.truncateSync(path, len) - 동기

 

디렉토리 추가

fs.mkdir(path, [mode], callback)

fs.mkdirSync(path, [mode])

 

디렉토리 삭제

fs.rmdir(path, callback)

fs.rmdirSync(path)

 

파일 혹은 디렉토리 이름 변경

fs.rename(oldPath, newPath, callback)

fs.renameSync(oldPath, newPath)

 

끝으로 Node.js에서 파일 시스템과 상호작용할 수 있는 fs 모듈을 통해 파일 생성, 읽기, 변경작업을 동기적, 비동기적으로 진행할 수 있고 디렉토리 구조 탐색이나 폴더 정보확인, 이름변경과 같은 작업을 할 수 있다.

 

'node.js' 카테고리의 다른 글

7. HTTP 서비스를 Node.js로 구현  (0) 2016.01.12
(express) 3. express로 시간 절약  (0) 2016.01.11
5. Node.js의 데이터 입출력 처리  (0) 2015.12.29
웹 지식  (0) 2015.12.29
1. Node.js의 개요  (0) 2015.11.25
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   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
글 보관함