5

我正在开发一个音乐地铁风格的应用程序。我从music library想要存储StorageFile对象的用户那里获取所有音乐文件,因为我不想一次又一次地检索。为此,我尝试序列化StorageFile对象并将其存储到XML. 从这里这里的示例中, 我尝试生成XML文件,但是在创建 XML 文件时会引发异常说

无法序列化类型“Windows.Storage.StorageFile”。考虑使用 DataContractAttribute 属性对其进行标记,并使用 DataMemberAttribute 属性标记您想要序列化的所有成员。如果该类型是一个集合,请考虑使用 CollectionDataContractAttribute 对其进行标记。有关其他支持的类型,请参阅 Microsoft .NET Framework 文档。

到目前为止,我的代码如下,

namespace CloudMusic.AppSettings
{
    [KnownType(typeof(CloudMusic.AppSettings.MusicFileDict))]
    [DataContractAttribute]
    public class MusicFileDict
    {
        [DataMember]
        public object musicStorageFile { get; set; }

        [DataMember]
        public int id { get; set; }
    }
}

从下面的班级我正在生成XML

class GenerateMusicDict
{    
        private const string filename = "musiclist.xml";
        static private List<MusicFileDict> _data = new List<MusicFileDict>();

        static public List<MusicFileDict> Data
        {
            get { return _data; }
        }
        static async public Task Save<T>()
        {
            await Windows.System.Threading.ThreadPool.RunAsync((sender) => GenerateMusicDict.SaveAsync<T>().Wait(), Windows.System.Threading.WorkItemPriority.Normal);
        }        

        internal static async Task SaveAsync<T>()
        {           
            GenerateMusicDict.GenerateMusicFileDict();           
            try
            {
                StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
                IRandomAccessStream sessionRandomAccess = await sessionFile.OpenAsync(FileAccessMode.ReadWrite);
                IOutputStream sessionOutputStream = sessionRandomAccess.GetOutputStreamAt(0);

                var sessionSerializer = new DataContractSerializer(typeof(List<MusicFileDict>), new Type[] { typeof(T) });
                sessionSerializer.WriteObject(sessionOutputStream.AsStreamForWrite(), _data);
                await sessionOutputStream.FlushAsync();
            }
            catch (Exception)
            {
            }

        }
        /// <summary>
        /// Generate music file dictonary according to songs ID
        /// </summary>
        /// <param name="musicFileList"></param>
        private static void GenerateMusicFileDict()
        {
            List<StorageFile> music_file_list = MusicFileDict.GetMusicList(); // At this stage i'll get all my music files,GetMusicList() function returns List<StorageFile>
            for (int i = 0; i < music_file_list.Count; i++)
            {
                _data.Add(new MusicFileDict { id = i, musicStorageFile = music_file_list[i]});          
            } 
        }
}

并使用我的主类调用 Save 方法

 await GenerateMusicDict.Save<MusicFileDict>(); 

在这一行的 SaveAsync() 函数上

 sessionSerializer.WriteObject(sessionOutputStream.AsStreamForWrite(), _data);

这是一句Exception谚语

无法序列化类型“Windows.Storage.StorageFile”。考虑使用 DataContractAttribute 属性对其进行标记,并使用 DataMemberAttribute 属性标记您想要序列化的所有成员。如果该类型是一个集合,请考虑使用 CollectionDataContractAttribute 对其进行标记。有关其他支持的类型,请参阅 Microsoft .NET Framework 文档。那么我该如何序列化呢?或者有什么方法可以存储和重复使用。请帮我

4

2 回答 2

3

利用 FutureAccessList http://msdn.microsoft.com/library/windows/apps/BR207457它应该提供您正在寻找的功能。

您可以通过引用文件的路径来检索和访问文件。这些路径可以很容易地存储和序列化(例如作为列表)。

如果您希望您的应用能够访问音乐库之外的用户内容,这也可以缓解您可能遇到的任何权限问题。

于 2013-03-15T21:11:05.080 回答
2

显然,从您的代码来看,您似乎正在尝试将音乐文件序列化到另一个文件中,这有点矫枉过正。因此,与其尝试序列化音乐,不如使用 URI 对其进行引用。

[DataContractAttribute]
public class MusicFileDict
{
    [DataMember]
    public Uri MusicFileUri { get; set; }

    [DataMember]
    public int Id { get; set; }
}

然后像这样创建你的对象

private static void GenerateMusicFileDict()
{
     List<StorageFile> music_file_list = MusicFileDict.GetMusicList(); 
     for (int i = 0; i < music_file_list.Count; i++)
     {
          StorageFile currentFile = music_file_list[i];

          _data.Add(new MusicFileDict 
                    { 
                        Id = i,
                        MusicFileUri = new Uri(currentFile.Path)
                    });          
     } 
}

如果您需要保留对您可以管理的音乐文件的引用,您可以将音乐文件复制到本地文件夹并引用此 URI 路径。但请记住,音乐文件可能很重,而且存储空间可能很宝贵,尤其是在 WinRT 设备上。

另一方面,请关闭您的流!

IRandomAccessStream sessionRandomAccess = null;

try
{
    StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
    sessionRandomAccess = await sessionFile.OpenAsync(FileAccessMode.ReadWrite);
    IOutputStream sessionOutputStream = sessionRandomAccess.GetOutputStreamAt(0);

    var sessionSerializer = new DataContractSerializer(typeof(List<MusicFileDict>), new Type[] { typeof(T) });
    sessionSerializer.WriteObject(sessionOutputStream.AsStreamForWrite(), _data);
    await sessionOutputStream.FlushAsync();
}
catch (Exception)
{
}
finally
{
    sessionRandomAccess.Dispose();
}
于 2012-12-23T12:56:09.320 回答