2013-03-22 100 views
3

我试图保持与Windows 8音乐库同步的数据库,但我仍未找到有效的解决方案。我知道.NET有一个FileSystemWatcher,它不适用于Windows 8应用程序。目前,我的想法是将GetFilesAsync返回的文件列表与我的数据库进行比较,并检查是否修改,删除或添加了某些内容。我知道这并不理想,但我在Windows.Storage找不到任何其他有用的东西。我的问题是,我想在音乐库修改后自动进行这些更新。当子文件夹中发生更改时,检查ModifiedDate文件夹是无用的。有没有人知道是否有方法可以说明StorageFolder何时被修改?识别StorageFolder中的文件更改

回答

0

我不认为你可以从你的Windows 8应用程序获取这些信息。最好的办法是异步查询文件夹和文件,并将信息与存储在数据库中的信息进行比较。查看枚举文件夹和文件here的一个示例。我知道这对你正在尝试做的事情不是很有效。如果您发现其他更好的方法,请分享。

0

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

0

这个工作对我来说:

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 
    } 
1

如果你能够得到ContentsChanged可靠地火,然后在下面的代码可以帮助你确定是什么改变了。

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

(我不能得到ContentsChanged可靠地火,而且,谷歌上搜索了几个小时之后,它似乎很多人有同样的问题)

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 
     }; 
    } 
+0

特里斯坦,我知道这是旧的文章,但你有没有图了解如何使'ContentsChanged'可靠地启动? – Laith 2015-08-30 08:36:24

+0

我希望。我最终编写了一个支持SQLite的通读缓存来保持文件系统的知识,包括一个低优先级的文件,它会检查所有已知的文件。 – Tristan 2015-08-31 05:09:51