2017-11-07 4 views
1

다음 코드가 한 번 읽은 후 서버의 메모리에있는 파일의 내용을 캐시하는지 알고 싶습니다. 내가 물어 보는 이유는 사용자가 페이지를 요청할 때마다 파일을 다시 읽고 싶지 않기 때문입니다. 첫 번째 읽기 후에 캐시 된 것을 선호합니다.fs.readFile()은 처음 읽은 후 서버의 메모리에 파일 내용을 캐시합니까?

fs.exists(fileName, function (exists) { 
     if (!exists) { 
      console.log("== 404 error"); 
      resp.writeHead(404, {'Content-Type': 'text/html'}); 
      resp.end(pageError); 
      return; 
     } 

     fs.readFile(fileName, 'utf8', function (err, data) { 
      if (err) { 
       resp.writeHead(404, {"Content-Type": "text/html"}); 
       resp.end(pageError); 
       return; 
      } 

      var contentType = getContentType(req.url); 
      var mimeType = mimeTypes[contentType]; 

      resp.writeHead(200, {"Content-Type": mimeType}); 
      resp.end(data); 
     }); 
    }); 

참고 ** 난 단지이 사용하는 내부 노드 JS 모듈을 수행하는 방법을 알고 싶어요 (어떠한 명시 적 없음)

+1

그냥 변수에 데이터를 저장하십시오. 사용자가 페이지를 요청할 때 서버를 시작할 필요가없는 이유는 무엇입니까? –

+0

효율적인 방법인가요? –

+0

효율적인 방법은 무엇입니까? 시작할 때 한 번 파일을 읽고 각 페이지 요청시 해당 데이터를 제공 할 수 있습니다. 파일을 다시 읽지 않으면 파일의 변경 사항이 반영되지 않습니다. –

답변

1

당신은 그것의 사용되지 않는 등 fs.exists()를 사용하지 말아야합니다; 대신 존재 확인 만하려면 fs.stat()을 사용하십시오. 존재 여부를 확인한 후 파일을 열고 읽으려는 경우 fs.readFile()을 사용하고 전달되지 않은 파일에 대해 전달 된 오류를 처리하십시오. 이 내용은 fs.access()에 대한 fs 문서에 나와 있지만 여전히 fs.stat()에도 적용됩니다. 아래는 Node.js 문서에서 발췌 한 내용입니다.

fs.open()을 호출하기 전에 fs.access()를 사용하여 파일의 액세스 가능성을 확인하면 fs.readFile() 또는 fs.writeFile()을 사용하지 않는 것이 좋습니다. 이렇게하면 다른 프로세스가 두 호출 사이에서 파일의 상태를 변경할 수 있기 때문에 경쟁 조건이 발생합니다. 대신 사용자 코드는 파일을 직접 열거 나 읽고 쓰고 파일에 액세스 할 수없는 경우 발생하는 오류를 처리해야합니다.

fs.readFile() 당신을 위해 캐싱을 수행하지 않습니다. 이것은 사용자가 직접 만들고 관리해야하는 항목입니다. 아래 예제는 JS Object를 사전으로 사용하여 파일 내용을 파일 이름으로 인덱싱 한 채로 파일 캐시를 만드는 방법을 보여줍니다. fileCache 개체에 데이터를 배치하지 않아야한다는 점에 유의해야합니다. 대신 많은 작은 파일에 유용합니다.

fileCachegetFileFromCache()의 범위에 있고 런타임 중에 가비지 수집되지 않는 위치에 있어야합니다.

const fileCache = {} 
const getFileFromCache = (filename, cb) => { 
    if (fileCache[filename]) { 
     return cb(null, fileCache[filename]) 
    } 

    fs.readFile(filename, 'utf8', (err, data) => { 
     if (err) { 
     return cb(err) 
     } 

     fileCache[filename] = data 
     return cb(null, data)  
    }) 
} 
+0

'fs.exists()'는 더 이상 사용되지 않을뿐만 아니라'fs.stat()'를 사용하는 이유도 없습니다. 'fs.readFile()'을 실행하고 파일이 없으면 오류를 처리하십시오. 보다 효율적이고 경기 조건에 영향을받지 않습니다. – jfriend00

+0

@ jfriend00 확실히, OP가 어떤 이유로 든 파일 통계에 액세스하기를 원하면 거기에 남겨 둡니다. 이 문제를 해결하기 위해 내 대답을 업데이트하겠습니다. – peteb

+0

@ jfriend00은 귀하가 제기 한 경쟁 조건을보다 잘 해결할 수 있도록 제 대답을 업데이트했습니다. – peteb

0

당신은 변수에 파일 데이터를 저장할 수, 또는 글로벌 변수에 여러 개의 모듈을 통해 액세스하려는 경우 (global.<varname> = <filedata>를 사용하여).

물론 George Cambpell이 말했듯이 파일을 다시 읽지 않으므로 파일에 대한 수정을 프로그램에서 발견 할 수 없습니다. 당신이 fs.readfile 진행 global.fileData에서 파일 내용을 저장하고 보내드립니다 있도록

function sendResponse(data) { 
    let contentType = getContentType(req.url); 
    let mimeType = mimeTypes[contentType]; 
    resp.writeHead(200, {"Content-Type": mimeType}); 
    resp.end(data); 
} 

if(global.fileData) { 
    return sendResponse(global.fileData); 
} 

fs.readFile(fileName, 'utf8', function (err, data) { 
    if (err) { 
     resp.writeHead(404, {"Content-Type": "text/html"}); 
     resp.end(pageError); 
     return; 
    } 

    global.fileData = data; 
    sendResponse(global.fileData); 
}); 

가 처음 global.fileData이 비어있을 것입니다 :

그래서 나는 같은 것을 할 것 응답.
두 번째로 global.fileData에 내용이 포함되므로 해당 내용으로 응답을 보내면 파일을 다시 읽지 않습니다. (가) 존재하기 때문에, 당신이해야 할 또 다른 점은 fs.access 또는 fs.stat와 fs.exists 교체입니다 https://nodejs.org/api/globals.html#globals_global

(나는 보통 fs.access 사용) : 더 참고로
공식 NodeJS 문서를 살펴 메소드가 사용되지 않습니다. 코딩
https://nodejs.org/api/fs.html#fs_fs_stat_path_callback
https://nodejs.org/api/fs.html#fs_fs_access_path_mode_callback

해피!

0

fs.readFile()은 처음 읽은 후 서버의 메모리에 파일의 내용을 캐시합니까?

fs.readFile() 자체는 캐싱을 수행하지 않습니다.

그러나 기본 운영 체제는 파일 캐싱을 수행하며 캐시 된 읽기가 플러시되는 많은 파일 활동이없는 한 OS는 로컬 메모리 캐쉬에서 파일을 가져옵니다. 두 번째, 세 번 읽으십시오.

캐싱을 확실하게하려면 처음 읽은 후에 콘텐츠를 저장해야하며 이전에 읽은 콘텐츠 만 사용할 수 있습니다.