C# 如何解决Microsoft.Phone.Storage.NativeFileStream漏洞

C# 如何解决Microsoft.Phone.Storage.NativeFileStream漏洞,c#,windows-phone-8,sd-card,C#,Windows Phone 8,Sd Card,在Windows Phone 8上,我使用ExternalStorageFile.OpenForReadAsync()从SD卡读取文件时遇到了一个问题,这是读取Windows Phone上SD卡文件的唯一方法 进一步调查发现,Microsoft.Phone.Storage.NativeFileStream中似乎有一个bug,这意味着Seek和SetFilePointer不能正常工作。给出了更多细节 有人对我如何解决这个平台错误有什么建议吗 我想也许我可以继承Microsoft.Phone.Sto

Windows Phone 8
上,我使用
ExternalStorageFile.OpenForReadAsync()
从SD卡读取文件时遇到了一个问题,这是读取Windows Phone上SD卡文件的唯一方法

进一步调查发现,
Microsoft.Phone.Storage.NativeFileStream
中似乎有一个bug,这意味着Seek和SetFilePointer不能正常工作。给出了更多细节

有人对我如何解决这个平台错误有什么建议吗

我想也许我可以继承Microsoft.Phone.Storage.NativeFileStream并重写错误的方法,但是
NativeFileStream
似乎不可用,我不确定正确的代码应该是什么。或者我可以将这个流强制到我自己的流类中,在那里我可以控制这些方法

也许我可以在开始时用垃圾填充我需要打开的文件,这样我就可以在“较长的32位高位”开始搜索了?该文件是特定于我的应用程序的,因此它不需要被其他任何东西打开


有什么新的想法吗?这是一个比我习惯处理的问题级别低的问题,所以请随时听取一些想法。

如果文件很小,那么您可以简单地将流复制到MemoryStream:

Stream s = await file.OpenForReadAsync();
MemoryStream ms = new MemoryStream();
s.CopyTo(ms);
但是,如果文件太大,您将遇到内存问题,因此可以使用以下流包装器类来纠正Microsoft的错误(尽管在Windows Phone的未来版本中,一旦错误得到修复,您需要禁用此修复):

使用系统;
使用System.IO;
命名空间WindowsPhoneBugFix
{
/// 
///流包装器,用于绕过ExternalStorageFile.OpenForReadAsync()返回的流的错误流读取
/// 
公共密封类ExternalStorageFileWrapper:流
{
私有流_Stream;//底层流
公共ExternalStorageFileWrapper(流)
{
if(流==null)
抛出新的ArgumentNullException(“流”);
_溪流=溪流;
}
//此处描述的解决方法-http://stackoverflow.com/a/21538189/250254
公共覆盖长寻道(长偏移,参见原始坐标系)
{
ulong uoffset=(ulong)偏移量;
ulong fix=((uoffset&0xffffffffffl)>32);
返回_stream.Seek((长)固定,原点);
}
公共覆盖布尔可读取
{
获取{return\u stream.CanRead;}
}
公共覆盖布尔搜索
{
获取{return\u stream.CanSeek;}
}
公共覆盖布尔可写
{
获取{return\u stream.CanWrite;}
}
公共覆盖无效刷新()
{
_stream.Flush();
}
公共覆盖长长度
{
获取{return\u stream.Length;}
}
公众优先多头仓位
{
得到
{
返回流位置;
}
设置
{
_流。位置=值;
}
}
公共重写整型读取(字节[]缓冲区、整型偏移量、整型计数)
{
返回_stream.Read(缓冲区、偏移量、计数);
}
公共覆盖无效设置长度(长值)
{
_stream.SetLength(值);
}
公共重写无效写入(字节[]缓冲区、整数偏移量、整数计数)
{
_写入(缓冲区、偏移量、计数);
}
}
}
此处有代码可用于访问您的项目:

较长部分的高32位似乎意味着
Seek
SetFilePointer
offset
参数的低32位被忽略。听起来你应该做的是像
long myOffset=some_number_字节@ChrisHayes-Cheers,但是看着其中突出显示的代码,似乎有一个更复杂的操作正在进行?我认为这只是做一些位转移,以确保在它们转换为
ulong
时没有任何中断,由于
>
运算符在
长时间
长时间
中的行为不同。老实说,我有点难说。
using System;
using System.IO;

namespace WindowsPhoneBugFix
{
    /// <summary>
    /// Stream wrapper to circumnavigate buggy Stream reading of stream returned by ExternalStorageFile.OpenForReadAsync()
    /// </summary>
    public sealed class ExternalStorageFileWrapper : Stream
    {
        private Stream _stream; // Underlying stream

        public ExternalStorageFileWrapper(Stream stream)
        {
            if (stream == null)
                throw new ArgumentNullException("stream");

            _stream = stream;
        }

        // Workaround described here - http://stackoverflow.com/a/21538189/250254
        public override long Seek(long offset, SeekOrigin origin)
        {
            ulong uoffset = (ulong)offset;
            ulong fix = ((uoffset & 0xffffffffL) << 32) | ((uoffset & 0xffffffff00000000L) >> 32);
            return _stream.Seek((long)fix, origin);
        }

        public override bool CanRead
        {
            get { return _stream.CanRead; }
        }

        public override bool CanSeek
        {
            get { return _stream.CanSeek; }
        }

        public override bool CanWrite
        {
            get { return _stream.CanWrite; }
        }

        public override void Flush()
        {
            _stream.Flush();
        }

        public override long Length
        {
            get { return _stream.Length; }
        }

        public override long Position
        {
            get
            {
                return _stream.Position;
            }
            set
            {
                _stream.Position = value;
            }
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            return _stream.Read(buffer, offset, count);
        }

        public override void SetLength(long value)
        {
            _stream.SetLength(value);
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            _stream.Write(buffer, offset, count);
        }
    }
}