디렉토리의 항목을 효율적으로 읽는 방법은 무엇입니까?

디렉토리의 항목을 효율적으로 읽는 방법은 무엇입니까?

내 프로그램이 호출 사이에 디렉터리에 파일이 추가되었는지 효율적으로 감지할 수 있기를 원합니다. 분석으로 인해 사용자 입력이 차단될 수 있으므로(이는 Fish 셸에 적용됨) 디렉터리가 크더라도 가능한 한 빨리 실행되기를 원합니다.

저는 표준 Unix로만 제한되어 있으므로 inotify에 액세스할 수 없습니다.

내가 생각한 한 가지 방법은 watch 디렉터리의 파일 목록을 해시 세트에 저장하고 분석할 때 전체 디렉터리를 읽고 해시 세트에 없는 항목이 있는지 확인하는 것입니다. 또 다른 접근 방식은 각 파일을 lstat하고 생성 시간을 비교하는 것입니다.

어쨌든 내 사용 사례에서는 두 가지 작업을 수행해야 합니다.

  • 각 항목에 대해 readdir을 호출합니다.
  • 각 항목에 대해 lstat를 호출합니다.(두 번째 솔루션을 사용하는 경우)

내 질문은 다음과 같습니다readdir과 lstat를 일괄 처리하는 효율적인 방법이 있습니까?

생각하다readdir은 시스템 호출이 아니라 SYS_getdents 시스템 호출을 둘러싼 래퍼이므로 아마도 일부 버퍼링을 수행하지만 얼마입니까? 얼마나 효율적인가요?

그리고 lstat는 시스템 호출 AFAIK를 래핑합니다. 동시에 많은 파일을 확인하고 각 파일에 대해 컨텍스트 전환 호출을 지불하고 싶지 않을 때 더 효율적인 버전이 있습니까?

답변1

네, 다른 방법이 있습니다 - getdents(). 거의 동일한 방식으로 작동 readdir()하지만 여러 항목을 한 번에 처리합니다. 따라서 구조체 배열에 메모리를 할당 linux_dirent하고 getdents()이를 채우려고 시도할 수 있습니다.
이것은 POSIX 기능이 아니므로 사용할 수 없다면 inotify(정말입니까???) 아마도 액세스 권한이 없는 것입니다 getdents().
그러나 결국 이것은 getdents()유사한 구조의 배열을 수동으로 반복하는 것과 다르지 않습니다. 래퍼가 아니므로 수동 루프보다 더 효율적일 수 있지만(오류 발생 가능성은 낮음) 효율성이 그다지 흥미롭지는 않습니다.readdir()direntgetdents()readdir()

새 파일이 디렉터리에 나타나거나 제거되는 시기를 아는 것이 목표라면 lstat()디렉터리 자체에 대해 알아볼 수 있습니다. mtime파일이 생성/삭제되면 디렉터리의 디렉터리가 수정됩니다. 파일 수정 사항은 파일 자체에 속하며 디렉터리 시간에 반영되지 않습니다.

관련 정보