Lacak perubahan sistem file di latar belakang
API penting
Kelas StorageLibraryChangeTracker memungkinkan aplikasi melacak perubahan dalam file dan folder saat pengguna memindahkannya di sekitar sistem. Dengan menggunakan kelas StorageLibraryChangeTracker, aplikasi dapat melacak:
- Operasi file termasuk menambahkan, menghapus, memodifikasi.
- Operasi folder seperti mengganti nama dan menghapus.
- File dan folder yang bergerak pada drive.
Gunakan panduan ini untuk mempelajari model pemrograman untuk bekerja dengan pelacak perubahan, melihat beberapa kode sampel, dan memahami berbagai jenis operasi file yang dilacak oleh StorageLibraryChangeTracker.
StorageLibraryChangeTracker berfungsi untuk pustaka pengguna, atau untuk folder apa pun di komputer lokal. Ini termasuk drive sekunder atau drive yang dapat dilepas tetapi tidak termasuk drive NAS atau drive jaringan.
Menggunakan pelacak perubahan
Pelacak perubahan diimplementasikan pada sistem sebagai buffer melingkar yang menyimpan operasi sistem file N terakhir. Aplikasi dapat membaca perubahan dari buffer dan kemudian memprosesnya ke dalam pengalaman mereka sendiri. Setelah aplikasi selesai dengan perubahan, aplikasi menandai perubahan sebagai diproses dan tidak akan pernah melihatnya lagi.
Untuk menggunakan pelacak perubahan pada folder, ikuti langkah-langkah berikut:
- Aktifkan pelacakan perubahan untuk folder.
- Tunggu perubahan.
- Membaca perubahan.
- Terima perubahan.
Bagian berikutnya menelusuri setiap langkah dengan beberapa contoh kode. Sampel kode lengkap disediakan di akhir artikel.
Mengaktifkan pelacak perubahan
Hal pertama yang perlu dilakukan aplikasi adalah memberi tahu sistem bahwa aplikasi tertarik untuk melacak perubahan pustaka tertentu. Ini dilakukan dengan memanggil metode Aktifkan pada pelacak perubahan untuk pustaka yang menarik.
StorageLibrary videosLib = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Videos);
StorageLibraryChangeTracker videoTracker = videosLib.ChangeTracker;
videoTracker.Enable();
Beberapa catatan penting:
- Pastikan aplikasi Anda memiliki izin ke pustaka yang benar dalam manifes sebelum membuat objek StorageLibrary. Lihat Izin Akses File untuk detail selengkapnya.
- Aktifkan aman utas, tidak akan mengatur ulang pointer Anda, dan dapat dipanggil sebanyak yang Anda suka (lebih lanjut tentang ini nanti).
Tunggu perubahan
Setelah pelacak perubahan diinisialisasi, pelacak perubahan akan mulai merekam semua operasi yang terjadi dalam pustaka, bahkan saat aplikasi tidak berjalan. Aplikasi dapat mendaftar untuk diaktifkan kapan saja ada perubahan dengan mendaftar untuk peristiwa StorageLibraryChangedTrigger.
Membaca perubahan
Aplikasi kemudian dapat melakukan polling untuk perubahan dari pelacak perubahan dan menerima daftar perubahan sejak terakhir kali diperiksa. Kode di bawah ini menunjukkan cara mendapatkan daftar perubahan dari pelacak perubahan.
StorageLibrary videosLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Videos);
videosLibrary.ChangeTracker.Enable();
StorageLibraryChangeReader videoChangeReader = videosLibrary.ChangeTracker.GetChangeReader();
IReadOnlyList changeSet = await changeReader.ReadBatchAsync();
Aplikasi ini kemudian bertanggung jawab untuk memproses perubahan ke dalam pengalaman atau databasenya sendiri sesuai kebutuhan.
Tip
Panggilan kedua untuk diaktifkan adalah mempertahankan terhadap kondisi balapan jika pengguna menambahkan folder lain ke pustaka saat aplikasi Anda membaca perubahan. Tanpa panggilan tambahan untuk Mengaktifkan kode akan gagal dengan ecSearchFolderScopeViolation (0x80070490) jika pengguna mengubah folder di pustaka mereka
Menerima perubahan
Setelah aplikasi selesai memproses perubahan, aplikasi harus memberi tahu sistem untuk tidak pernah menampilkan perubahan tersebut lagi dengan memanggil metode AcceptChangesAsync.
await changeReader.AcceptChangesAsync();
Aplikasi ini sekarang hanya akan menerima perubahan baru saat membaca pelacak perubahan di masa mendatang.
- Jika perubahan telah terjadi antara memanggil ReadBatchAsync dan AcceptChangesAsync, penunjuk hanya akan dimajukan ke perubahan terbaru yang telah dilihat aplikasi. Perubahan lain tersebut masih akan tersedia saat berikutnya memanggil ReadBatchAsync.
- Tidak menerima perubahan akan menyebabkan sistem mengembalikan kumpulan perubahan yang sama saat berikutnya aplikasi memanggil ReadBatchAsync.
Hal-hal penting untuk diingat
Saat menggunakan pelacak perubahan, ada beberapa hal yang harus Anda ingat untuk memastikan bahwa semuanya berfungsi dengan benar.
Buffer overruns
Meskipun kami mencoba memesan cukup ruang di pelacak perubahan untuk menahan semua operasi yang terjadi pada sistem sampai aplikasi Anda dapat membacanya, sangat mudah untuk membayangkan skenario di mana aplikasi tidak membaca perubahan sebelum buffer melingkar menimpa dirinya sendiri. Terutama jika pengguna memulihkan data dari cadangan atau menyinkronkan kumpulan gambar yang besar dari ponsel kamera mereka.
Dalam hal ini, ReadBatchAsync akan mengembalikan kode kesalahan StorageLibraryChangeType.ChangeTrackingLost. Jika aplikasi Anda menerima kode kesalahan ini, itu berarti beberapa hal:
- Buffer telah menimpa dirinya sendiri sejak terakhir kali Anda melihatnya. Tindakan terbaik adalah mengulangi pustaka, karena informasi apa pun dari pelacak tidak akan lengkap.
- Pelacak perubahan tidak akan mengembalikan perubahan lagi hingga Anda memanggil Reset. Setelah aplikasi memanggil reset, pointer akan dipindahkan ke perubahan terbaru dan pelacakan akan dilanjutkan secara normal.
Seharusnya jarang mendapatkan kasus-kasus ini, tetapi dalam skenario di mana pengguna memindahkan sejumlah besar file di disk mereka, kami tidak ingin pelacak perubahan untuk balon dan mengambil terlalu banyak penyimpanan. Ini harus memungkinkan aplikasi untuk bereaksi terhadap operasi sistem file besar-besaran sambil tidak merusak pengalaman pelanggan di Windows.
Perubahan pada StorageLibrary
Kelas StorageLibrary ada sebagai grup virtual folder akar yang berisi folder lain. Untuk mendamaikan ini dengan pelacak perubahan sistem file, kami membuat pilihan berikut:
- Setiap perubahan pada turunan folder pustaka akar akan diwakili dalam pelacak perubahan. Folder pustaka akar dapat ditemukan menggunakan properti Folder.
- Menambahkan atau menghapus folder akar dari StorageLibrary (melalui RequestAddFolderAsync dan RequestRemoveFolderAsync) tidak akan membuat entri di pelacak perubahan. Perubahan ini dapat dilacak melalui peristiwa DefinitionChanged atau dengan menghitung folder akar di pustaka menggunakan properti Folder.
- Jika folder dengan konten yang sudah ada di dalamnya ditambahkan ke pustaka, tidak akan ada pemberitahuan perubahan atau entri pelacak perubahan yang dihasilkan. Setiap perubahan berikutnya pada turunan folder tersebut akan menghasilkan pemberitahuan dan mengubah entri pelacak.
Memanggil metode Aktifkan
Aplikasi harus memanggil Aktifkan segera setelah mereka mulai melacak sistem file dan sebelum setiap enumerasi perubahan. Ini akan memastikan bahwa semua perubahan akan diambil oleh pelacak perubahan.
Menempatkannya bersama-sama
Berikut adalah semua kode yang digunakan untuk mendaftar perubahan dari pustaka video dan mulai menarik perubahan dari pelacak perubahan.
private async void EnableChangeTracker()
{
StorageLibrary videosLib = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Videos);
StorageLibraryChangeTracker videoTracker = videosLib.ChangeTracker;
videoTracker.Enable();
}
private async void GetChanges()
{
StorageLibrary videosLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Videos);
videosLibrary.ChangeTracker.Enable();
StorageLibraryChangeReader videoChangeReader = videosLibrary.ChangeTracker.GetChangeReader();
IReadOnlyList changeSet = await changeReader.ReadBatchAsync();
//Below this line is for the blog post. Above the line is for the magazine
foreach (StorageLibraryChange change in changeSet)
{
if (change.ChangeType == StorageLibraryChangeType.ChangeTrackingLost)
{
//We are in trouble. Nothing else is going to be valid.
log("Resetting the change tracker");
videosLibrary.ChangeTracker.Reset();
return;
}
if (change.IsOfType(StorageItemTypes.Folder))
{
await HandleFileChange(change);
}
else if (change.IsOfType(StorageItemTypes.File))
{
await HandleFolderChange(change);
}
else if (change.IsOfType(StorageItemTypes.None))
{
if (change.ChangeType == StorageLibraryChangeType.Deleted)
{
RemoveItemFromDB(change.Path);
}
}
}
await changeReader.AcceptChangesAsync();
}