2

オブジェクトをメモリ ストリームにシリアル化し、このストリームを暗号化してファイルに書き込もうとしています。何が問題なのかわかりません。「復号化」後にメモリ ストリームが空です。

    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);
    }
4

2 に答える 2

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);
}
于 2012-04-22T16:07:46.373 に答える
0

最後に投稿された回答に加えて、raStream は IDisposable オブジェクトであるため、using ステートメントでラップする必要があります。そうしないと、コードが後でファイルを再度開こうとすると、ランダム アクセス ストリームによってファイルがまだ開かれているため、アクセスが拒否されて失敗します。

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();
                }
            }
        }
于 2013-11-14T15:47:20.407 に答える