如何解决 Microsoft.Phone.Storage.NativeFileStream 错误 [英] How to work-around Microsoft.Phone.Storage.NativeFileStream bug

查看:63
本文介绍了如何解决 Microsoft.Phone.Storage.NativeFileStream 错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

On Windows Phone 8 I have run in to an issue while reading files from the SD card using ExternalStorageFile.OpenForReadAsync(), which is the only way to read an SD card located file on Windows Phone.

进一步调查似乎 Microsoft.Phone.Storage.NativeFileStream 有一个错误,这意味着 Seek 和 SetFilePointer 无法正常工作.此处提供了更多详细信息.

Investigating further it seems that the Microsoft.Phone.Storage.NativeFileStream has a bug in it which means Seek and SetFilePointer don't work as they should. More detail is given here.

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

Does anyone have any suggestions how I can work-around this platform bug?

我想也许我可以从 Microsoft.Phone.Storage.NativeFileStream 继承并覆盖有问题的方法,但是 NativeFileStream 似乎不可用,我不知道正确的代码应该是什么.或者我可以将这个 Stream 强制到我自己的 Stream 类中,在那里我可以控制这些方法?

I thought maybe I could inherit from Microsoft.Phone.Storage.NativeFileStream and override the buggy methods, but NativeFileStream doesn't seem to be available and I'm not sure what the correct code should be anyway. Or perhaps I can force this Stream into my own Stream class where I can control these methods?

也许我可以在开始时用垃圾填充我需要打开的文件,以便我可以在长的更高 32 位"中开始我的搜索?该文件特定于我的应用程序,因此无需通过其他任何方式打开.

Perhaps I could pad the file I need to open with garbage at the beginning so I can start my seeks in the "higher 32bits of the long"? The file is specific to my app so it doesn't need to be opened by anything else.

任何解决方法的想法?有点比我习惯处理的低级问题,所以请继续听取一些想法.

Any ideas for a work-around? A bit of a lower level problem than I'm used to dealing with so keep to hear some ideas.

推荐答案

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

If the file is small then you can simply copy the stream to a MemoryStream:

Stream s = await file.OpenForReadAsync();
MemoryStream ms = new MemoryStream();
s.CopyTo(ms);

但是,如果文件太大,您将遇到内存问题,因此可以使用以下流包装器类来纠正 Microsoft 的错误(尽管在 Windows Phone 的未来版本中,一旦错误已修复):

However, if the file is too large you'll run in to memory issues so the following stream wrapper class can be used to correct Microsoft's bug (though in future versions of Windows Phone you'll need to disable this fix once the bug has been fixed):

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

代码可在此处加入您的项目:https://github.com/gavinharriss/ExternalStorageFileWrapper-wp8

Code is available here to drop in to your project: https://github.com/gavinharriss/ExternalStorageFileWrapper-wp8

这篇关于如何解决 Microsoft.Phone.Storage.NativeFileStream 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆