我正在开发一个音乐地铁风格的应用程序。我从用户music library
获取所有音乐文件我想存储StorageFile
对象,因为我不想一次又一次地检索。为此,我尝试序列化StorageFile
对象和将其存储到XML
。从示例here和here我尝试生成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文档。 那我该怎么序列化呢?或者有什么方法可以存储它并重复使用。请帮帮我
答案 0 :(得分:3)
利用FutureAccessList http://msdn.microsoft.com/library/windows/apps/BR207457它应该提供您正在寻找的功能。
您可以通过引用其路径来检索和访问文件。可以轻松地存储和序列化这些路径(例如,作为列表)。
如果您希望应用能够访问音乐库之外的用户内容,这还可以缓解您可能遇到的任何权限问题。
答案 1 :(得分: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();
}