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