Windows 8 识别StorageFolder中的文件更改

Windows 8 识别StorageFolder中的文件更改,windows-8,windows-runtime,windows-store-apps,Windows 8,Windows Runtime,Windows Store Apps,我正在努力使一个数据库与Windows8音乐库保持同步,但我还没有找到一个有效的解决方案。我知道.NET有一个Windows 8应用程序无法使用的文件系统监视程序。目前,我的想法是将getfileasync返回的文件列表与我的数据库进行比较,并检查是否有修改、删除或添加的内容。我知道这并不理想,但我在Windows.Storage中找不到任何其他有用的东西。我的问题是,一旦对音乐库进行了修改,我想自动进行这些更新。当更改发生在子文件夹中时,检查文件夹的ModifiedDate是无用的。有人知道有

我正在努力使一个数据库与Windows8音乐库保持同步,但我还没有找到一个有效的解决方案。我知道.NET有一个Windows 8应用程序无法使用的
文件系统监视程序。目前,我的想法是将
getfileasync
返回的文件列表与我的数据库进行比较,并检查是否有修改、删除或添加的内容。我知道这并不理想,但我在
Windows.Storage
中找不到任何其他有用的东西。我的问题是,一旦对音乐库进行了修改,我想自动进行这些更新。当更改发生在子文件夹中时,检查文件夹的
ModifiedDate
是无用的。有人知道有没有办法告诉你什么时候修改了
StorageFolder

我认为你无法从Windows 8应用程序中获得这些信息。最好是异步查询文件夹和文件,并将信息与存储在数据库中的信息进行比较。请参见枚举文件夹和文件的一个示例。我知道这对你正在做的事情来说不是很有效。如果您找到其他更好的方法,请与他人共享。

您可以使用及其
内容更改事件来通知文件夹及其子文件夹的更改。但是,该事件不包含有关实际更改内容的任何信息,因此您需要重新分析文件夹,并检查您感兴趣的内容是否已被修改。

这对我很有用:

    public async void ListenAsync() {
        query = storageFolder.CreateFileQuery();
        query.ContentsChanged += query_ContentsChanged;
        var files = await query.GetFilesAsync();
    }

    void query_ContentsChanged(IStorageQueryResultBase sender, object args) {
        // args has no info about what changed. check manually
    }

如果您能够可靠地触发
内容更改
,那么下面的代码可能会帮助您确定更改的内容

注意,它并不快
GetBasicPropertiesAsync
似乎需要~5ms/文件。。。因此,大约需要10秒来区分一组1000个文件

(我无法让
ContentsChanged
可靠地启动,在谷歌搜索数小时后,许多其他人似乎也有同样的问题)

私有类DiffSet
{
公共IReadOnlyList添加了{get;set;}
公共IReadOnlyList已删除{get;set;}
公共IReadOnlyList已更改{get;set;}
}
私有静态异步任务差异(IEnumerable oldSet、IEnumerable newSet)
{
var newAsDict=newSet.ToDictionary(sf=>sf.Path);
var added=新列表();
var deleted=新列表();
var changed=新列表();
var fromOldSet=newhashset();
foreach(旧集中的var oldFile)
{
如果(!newAsDict.ContainsKey(oldFile.Path))
{
删除。添加(旧文件);
继续;
}
var oldBasicProperties=await oldFile.GetBasicPropertiesAsync();
var newBasicProperties=wait newAsDict[oldFile.Path].GetBasicProperties异步();
var oldDateModified=oldBasicProperties.DateModified;
var newDateModified=newBasicProperties.DateModified;
如果(oldDateModified!=newDateModified)
{
已更改。添加(旧文件);
}
fromOldSet.Add(oldFile.Path);
}
foreach(新闻集中的var newFile)
{
如果(!fromOldSet.Contains(newFile.Path))
added.Add(新文件);
}
返回新扩散集
{
添加的,
已删除=已删除,
改变
};
}

Tristan,我知道这是一篇老文章,但你有没有想过如何让
ContentsChanged
可靠地开火?我希望如此。最后,我编写了一个SQLite支持的直通式缓存来维护对文件系统的了解,其中包括一个以低优先级对所有已知文件进行双重检查的部分。
    private class DiffSet
    {
        public IReadOnlyList<StorageFile> Added { get; set; }
        public IReadOnlyList<StorageFile> Deleted { get; set; }
        public IReadOnlyList<StorageFile> Changed { get; set; }
    }

    private static async Task<DiffSet> Diff(IEnumerable<StorageFile> oldSet, IEnumerable<StorageFile> newSet)
    {
        var newAsDict = newSet.ToDictionary(sf => sf.Path);

        var added = new List<StorageFile>();
        var deleted = new List<StorageFile>();
        var changed = new List<StorageFile>();

        var fromOldSet = new HashSet<string>();

        foreach (var oldFile in oldSet)
        {
            if (!newAsDict.ContainsKey(oldFile.Path))
            {
                deleted.Add(oldFile);
                continue;
            }

            var oldBasicProperties = await oldFile.GetBasicPropertiesAsync();
            var newBasicProperties = await newAsDict[oldFile.Path].GetBasicPropertiesAsync();

            var oldDateModified = oldBasicProperties.DateModified;
            var newDateModified = newBasicProperties.DateModified;

            if (oldDateModified != newDateModified)
            {
                changed.Add(oldFile);
            }

            fromOldSet.Add(oldFile.Path);
        }

        foreach (var newFile in newSet)
        {
            if (!fromOldSet.Contains(newFile.Path))
                added.Add(newFile);
        }

        return new DiffSet
        {
            Added = added,
            Deleted = deleted,
            Changed = changed
        };
    }