2012-04-19 36 views
2

我试图序列化一个对象到内存流,然后加密这个流,然后将它写入到一个文件。无法弄清楚什么是错误的,'解密'后内存流是空的。使用DataContractSerializer和DataProtectionProvider序列化和加密对象

public static async Task SerializeToFileEncrypt<T>(T o, StorageFile file) 
    { 
      DataContractSerializer dsc = new DataContractSerializer(typeof(T));     
      MemoryStream memoryStream = new MemoryStream(); 
      dsc.WriteObject(memoryStream, o); 
      DataProtectionProvider provider = new DataProtectionProvider("Local=User"); 
      var raStream = await file.OpenAsync(FileAccessMode.ReadWrite); 
      using(var filestream = raStream.GetOutputStreamAt(0)) 
      { 
       await provider.ProtectStreamAsync(memoryStream.AsInputStream(), filestream); 
       await filestream.FlushAsync();       
      } 
    } 

    public static async Task<T> DeserializeFromFileDecrypt<T>(StorageFile file) 
    { 
     DataContractSerializer dsc = new DataContractSerializer(typeof(T)); 
     MemoryStream memoryStream = new MemoryStream(); 
     DataProtectionProvider provider = new DataProtectionProvider(); 
     await provider.UnprotectStreamAsync((await file.OpenStreamForReadAsync()).AsInputStream(), memoryStream.AsOutputStream()); 
     return (T) dsc.ReadObject(memoryStream); 
    } 

回答

3

您需要在完成写入操作后移至MemoryStream的开头。否则没有什么可读的,因为你已经定位在最后。

这应该工作:

public static async Task SerializeToFileEncrypt<T>(T o, StorageFile file) 
{ 
     DataContractSerializer dsc = new DataContractSerializer(typeof(T));     
     MemoryStream memoryStream = new MemoryStream(); 
     dsc.WriteObject(memoryStream, o); 
     memoryStream.Seek(0, SeekOrigin.Begin); // move to the beginning of the stream 
     DataProtectionProvider provider = new DataProtectionProvider("Local=User"); 
     var raStream = await file.OpenAsync(FileAccessMode.ReadWrite); 
     using(var filestream = raStream.GetOutputStreamAt(0)) 
     { 
      await provider.ProtectStreamAsync(memoryStream.AsInputStream(), filestream); 
      await filestream.FlushAsync();       
     } 
} 

public static async Task<T> DeserializeFromFileDecrypt<T>(StorageFile file) 
{ 
    DataContractSerializer dsc = new DataContractSerializer(typeof(T)); 
    MemoryStream memoryStream = new MemoryStream(); 
    DataProtectionProvider provider = new DataProtectionProvider(); 
    await provider.UnprotectStreamAsync((await file.OpenStreamForReadAsync()).AsInputStream(), memoryStream.AsOutputStream()); 
    memoryStream.Seek(0, SeekOrigin.Begin); // move to the beginning of the stream 
    return (T) dsc.ReadObject(memoryStream); 
} 
0

其中除了最后公布答案,你需要用的raStream在using语句,因为它是一个IDisposable的对象。否则,如果稍后某些代码尝试再次打开该文件,则该文件将由于随机访问流仍然打开而导致访问被拒绝而失败。

public static async Task SerializeToFileEncrypt<T>(T o, StorageFile file) 
     { 
      DataContractSerializer dsc = new DataContractSerializer(typeof(T)); 
      MemoryStream memoryStream = new MemoryStream(); 
      dsc.WriteObject(memoryStream, o); 
      memoryStream.Seek(0, SeekOrigin.Begin); // move to the beginning of the stream 
      DataProtectionProvider provider = new DataProtectionProvider("Local=User"); 
      using (var raStream = await file.OpenAsync(FileAccessMode.ReadWrite)) 
      { 
       using (var filestream = raStream.GetOutputStreamAt(0)) 
       { 
        await provider.ProtectStreamAsync(memoryStream.AsInputStream(), filestream); 
        await filestream.FlushAsync(); 
       } 
      } 
     } 
相关问题