Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Основные API
- StorageLibraryChangeTracker
- StorageLibraryChangeReader
- ТриггерИзмененияБиблиотекиХранилища
- StorageLibrary
Класс StorageLibraryChangeTracker позволяет приложениям отслеживать изменения в файлах и папках по мере перемещения пользователей по системе. С помощью класса StorageLibraryChangeTracker приложение может отслеживать:
- Операции с файлами, включая добавление, удаление, изменение.
- Операции папок, такие как переименование и удаление.
- Файлы и папки, перемещающиеся на диске.
Используйте это руководство для изучения модели программирования для работы с средством отслеживания изменений, просмотра примера кода и понимания различных типов операций файлов, отслеживаемых StorageLibraryChangeTracker.
StorageLibraryChangeTracker работает для пользовательских библиотек или для любой папки на локальном компьютере. К ним относятся вторичные диски или съемные диски, но не включают диски NAS или сетевые диски.
Использование средства отслеживания изменений
Средство отслеживания изменений реализуется в системе в виде циклического буфера, в котором хранятся последние N операций файловой системы. Приложения могут считывать изменения из буфера, а затем обрабатывать их в собственных интерфейсах. Когда приложение завершится с изменениями, они помечают изменения как обработанные и никогда не увидят их снова.
Чтобы использовать средство отслеживания изменений в папке, выполните следующие действия.
- Включите отслеживание изменений для папки.
- Дождитесь изменений.
- Прочитайте изменения.
- Примите изменения.
В следующих разделах описывается каждый из шагов с некоторыми примерами кода. Полный пример кода представлен в конце статьи.
Включение средства отслеживания изменений
Первое, что нужно сделать приложению, заключается в том, чтобы сообщить системе, что она заинтересована в отслеживании изменений данной библиотеки. Это делается путем вызова метода Enable в средстве отслеживания изменений для интересующей библиотеки.
StorageLibrary videosLib = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Videos);
StorageLibraryChangeTracker videoTracker = videosLib.ChangeTracker;
videoTracker.Enable();
Несколько важных примечаний:
- Перед созданием объекта StorageLibrary убедитесь, что приложение имеет разрешение на правильную библиотеку в манифесте. Дополнительные сведения см. в разделе разрешения доступа к файлам.
- Включение является потокобезопасным, не сбрасывает ваш указатель и может вызываться столько раз, сколько вам хочется (подробнее об этом позже).
Дождитесь изменений
После инициализации средства отслеживания изменений начнется запись всех операций, происходящих в библиотеке, даже если приложение не запущено. Приложения могут быть активированы в любой момент, когда есть изменение, зарегистрируясь для события StorageLibraryChangedTrigger.
Прочитайте изменения
Затем приложение может проверить на наличие изменений из трекера изменений и получить список изменений с момента последнего раза, когда оно проверяло. В приведенном ниже коде показано, как получить список изменений из средства отслеживания изменений.
StorageLibrary videosLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Videos);
videosLibrary.ChangeTracker.Enable();
StorageLibraryChangeReader videoChangeReader = videosLibrary.ChangeTracker.GetChangeReader();
IReadOnlyList changeSet = await changeReader.ReadBatchAsync();
Затем приложение отвечает за обработку изменений в собственном интерфейсе или базе данных по мере необходимости.
Подсказка
Второй вызов функции включения необходим для защиты от состояния гонки, если пользователь добавляет другую папку в библиотеку, пока ваше приложение обрабатывает изменения. Без дополнительного вызова Enable код завершится ошибкой ecSearchFolderScopeViolation (0x80070490), если пользователь изменяет папки в своей библиотеке.
Примите изменения
После завершения обработки изменений приложение должно сообщить системе никогда не отображать эти изменения снова путем вызова метода AcceptChangesAsync .
await changeReader.AcceptChangesAsync();
Теперь приложение получит новые изменения только при чтении средства отслеживания изменений в будущем.
- Если изменения произошли между вызовом ReadBatchAsync и AcceptChangesAsync, указатель будет перемещен только к последнему обнаруженному изменению приложением. Эти другие изменения по-прежнему будут доступны при следующем вызове ReadBatchAsync.
- Не принимать изменения приведет к тому, что система возвращает тот же набор изменений при следующем вызове ReadBatchAsync.
Важные вещи, которые нужно запомнить
При использовании средства отслеживания изменений есть несколько вещей, о которых вам следует помнить, чтобы убедиться, что все работает правильно.
Переполнение буфера
Хотя мы пытаемся зарезервировать достаточно места в отслеживании изменений, чтобы хранить все операции, происходящие в системе, пока приложение не сможет их прочитать, очень легко представить сценарий, в котором приложение не считывает изменения, прежде чем циклический буфер перезаписывает себя. Особенно если пользователь восстанавливает данные из резервной копии или синхронизирует большую коллекцию фотографий с телефона камеры.
В этом случае ReadBatchAsync вернет код ошибки StorageLibraryChangeType.ChangeTrackingLost. Если приложение получает этот код ошибки, это означает несколько вещей:
- Буфер перезаписал себя с момента последнего просмотра. Лучший план действий заключается в том, чтобы пересканировать библиотеку, потому что любая информация от трекера будет неполной.
- Средство отслеживания изменений больше не будет возвращать изменения до тех пор, пока вы не вызовете Сброс. После вызова reset приложением указатель будет перемещён к последнему изменению, и отслеживание возобновится нормально.
Такие случаи должны быть редкими, но в сценариях, когда пользователь перемещает по своему диску большое количество файлов, мы не хотим, чтобы средство отслеживания изменений раздувалось и занимало слишком много места. Это должно позволить приложениям реагировать на массовые операции файловой системы, не повреждая взаимодействие с клиентами в Windows.
Изменения в StorageLibrary
Класс StorageLibrary существует как виртуальная группа корневых папок, содержащих другие папки. Чтобы согласовать это со средством отслеживания изменений файловой системы, мы сделали следующие выборы:
- Все изменения, внесенные в потомки папок корневой библиотеки, будут представлены в средстве отслеживания изменений. Папки корневой библиотеки можно найти с помощью свойства папок .
- Добавление или удаление корневых папок из storageLibrary (с помощью RequestAddFolderAsync и RequestRemoveFolderAsync) не создаст запись в отслеживании изменений. Эти изменения можно отслеживать с помощью события DefinitionChanged или перечисления корневых папок в библиотеке с помощью свойства "Папки ".
- Если в библиотеку добавляется папка с содержимым, уже содержащаяся в ней, уведомления об изменении или записи отслеживания изменений не создаются. Любые последующие изменения в потомках этой папки будут создавать уведомления и записи в журнале отслеживания изменений.
Вызов метода Enable
Приложения должны вызывать Enable сразу после того, как начинают отслеживание файловой системы, и перед каждым перечислением изменений. Это гарантирует, что все изменения будут записаны средством отслеживания изменений.
Собирая это вместе
Ниже приведен весь код, который используется для регистрации изменений из видеотеки и начала извлечения изменений из средства отслеживания изменений.
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();
}