Maison > Article > développement back-end > Comment détecter efficacement les modifications de fichiers sur un volume NTFS à l'aide de FSCTL_ENUM_USN_DATA ?
Les méthodes de sauvegarde existantes, qui vérifient le bit d'archive de chaque fichier, peuvent devenir lentes et inefficace pour les grands systèmes de fichiers. Cette approche nécessite d'analyser tous les fichiers, y compris les fichiers temporaires, et peut entraîner de longs processus de sauvegarde.
Une méthode plus efficace consiste à utiliser le système de fichiers USN (séquence de mise à jour Numéro) journal des changements. Le système de fichiers USN fournit un enregistrement pour chaque modification apportée au système de fichiers, y compris la création, la suppression et la modification de fichiers.
Pour détecter les modifications sur un volume NTFS, nous pouvons utiliser le Code de contrôle FSCTL_ENUM_USN_DATA. Ce code de contrôle :
Récupère les données critiques pour chaque fichier, notamment :
Pour détecter les changements :
Voici un extrait de code qui illustre l'approche :
<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>
L'approche utilisant FSCTL_ENUM_USN_DATA offre :
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!