>  기사  >  백엔드 개발  >  FSCTL_ENUM_USN_DATA를 사용하여 NTFS 볼륨의 파일 변경 사항을 어떻게 효율적으로 감지할 수 있습니까?

FSCTL_ENUM_USN_DATA를 사용하여 NTFS 볼륨의 파일 변경 사항을 어떻게 효율적으로 감지할 수 있습니까?

Patricia Arquette
Patricia Arquette원래의
2024-10-30 13:03:26815검색

 How Can You Efficiently Detect File Changes on an NTFS Volume Using FSCTL_ENUM_USN_DATA?

FSCTL_ENUM_USN_DATA를 사용하여 NTFS 볼륨에서 파일 변경 사항을 효율적으로 감지

백그라운드

각 파일의 보관 비트를 확인하는 기존 백업 방법은 속도가 느려지고 대용량 파일 시스템에는 비효율적입니다. 이 접근 방식을 사용하려면 임시 파일을 포함한 모든 파일을 검사해야 하며 백업 프로세스 시간이 길어질 수 있습니다.

파일 시스템 USN을 사용하는 대체 접근 방식

보다 효율적인 방법은 파일 시스템 USN(업데이트 시퀀스)을 사용하는 것입니다. 번호) 일지를 변경합니다. 파일 시스템 USN은 파일 생성, 삭제 및 수정을 포함하여 파일 시스템에 발생한 각 변경 사항에 대한 기록을 제공합니다.

FSCTL_ENUM_USN_DATA 작동 방식

NTFS 볼륨의 변경 사항을 감지하려면 FSCTL_ENUM_USN_DATA 제어 코드입니다. 이 제어 코드는 다음과 같습니다.

  • 현재 존재하는 파일만 포함하여 볼륨의 모든 파일을 열거합니다.
  • 다음을 포함하여 각 파일에 대한 중요한 데이터를 검색합니다.

    • 파일 플래그
    • USN
    • 파일 이름
    • 상위 파일 참조 번호

변경 감지 구현

변경 사항을 검색하려면:

  1. 파일 시스템 USN 데이터 가져오기: FSCTL_QUERY_USN_JOURNAL을 사용하여 시스템의 최대 USN(maxusn)을 가져옵니다.
  2. USN 레코드 열거: 루프를 사용하여 FSCTL_ENUM_USN_DATA를 사용하여 USN 레코드를 반복합니다.
  3. 관련 레코드 식별: 플래그를 확인하고 USN을 비교하여 생성, 삭제 또는 수정된 파일을 감지합니다.
  4. 상위 경로 해결: 상위 파일 참조 번호를 디렉터리의 파일 참조 번호와 일치시켜 전체 파일 경로를 얻습니다.

C의 코드 예

다음은 접근 방식을 보여주는 코드 조각입니다.

<code class="c++">DWORDLONG nextid;
DWORDLONG filecount = 0;
DWORD starttick, endtick;

// Allocate memory for USN records
void * buffer = VirtualAlloc(NULL, BUFFER_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

// Open volume handle
HANDLE drive = CreateFile(L"\\?\c:", GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_FLAG_NO_BUFFERING, NULL);

// Get volume USN journal data
USN_JOURNAL_DATA * journal = (USN_JOURNAL_DATA *)buffer;
if (!DeviceIoControl(drive, FSCTL_QUERY_USN_JOURNAL, NULL, 0, buffer, BUFFER_SIZE, &bytecount, NULL)) {
  (...)
}
maxusn = journal->MaxUsn;

MFT_ENUM_DATA mft_enum_data;
mft_enum_data.StartFileReferenceNumber = 0;
mft_enum_data.LowUsn = 0;
mft_enum_data.HighUsn = maxusn;

while (...) {
  if (!DeviceIoControl(drive, FSCTL_ENUM_USN_DATA, &mft_enum_data, sizeof(mft_enum_data), buffer, BUFFER_SIZE, &bytecount, NULL)) {
    (...)
  }

  nextid = *((DWORDLONG *)buffer);
  USN_RECORD * record = (USN_RECORD *)((USN *)buffer + 1);
  USN_RECORD * recordend = (USN_RECORD *)(((BYTE *)buffer) + bytecount);

  while (record < recordend) {
    filecount++;
    // Check flags and USNs to identify changes
    (...)
    record = (USN_RECORD *)(((BYTE *)record) + record->RecordLength);
  }
  mft_enum_data.StartFileReferenceNumber = nextid;
}</code>

성능 고려 사항

FSCTL_ENUM_USN_DATA를 사용하는 접근 방식은 다음을 제공합니다.

  • 빠른 열거 프로세스: 초당 6000개 이상의 레코드 처리 가능.
  • 효율적인 필터링: 관련 파일 변경 기록만 분석하여 임시 파일의 오버헤드를 제거합니다.
  • 잠재력 제한 사항: 성능은 매우 큰 볼륨에 따라 달라질 수 있지만 일반적으로 보관 비트를 확인하는 것보다 더 효율적입니다.

추가 참고 사항

  • Windows에서 MFT_ENUM_DATA를 MFT_ENUM_DATA_V0으로 바꾸세요. Windows 7 이후 버전.
  • 파일 참조 번호가 32비트로 인쇄되는데 이는 실수입니다. 프로덕션 코드에서는 64비트 값을 사용하는 것이 좋습니다.

위 내용은 FSCTL_ENUM_USN_DATA를 사용하여 NTFS 볼륨의 파일 변경 사항을 어떻게 효율적으로 감지할 수 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.