从SDCard加载文件

时间:2014-01-28 13:02:01

标签: c# file windows-phone-8 windows-phone

我将(this)EPUB Reader读者集成到我的项目中。它工作正常。 &安培;我想从SDCard加载文件而不是设备的隔离存储

要从隔离存储中打开文件,我们有IsolatedStorageFileStream这样的

IsolatedStorageFileStream isfs;
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
    try
    {
        isfs = isf.OpenFile([Path to file], FileMode.Open);
    }
    catch
    {
        return;
    }
}

ePubView.Source = isfs;

对于SDcard中的文件我试过这个

ExternalStorageDevice sdCard = (await ExternalStorage.GetExternalStorageDevicesAsync()).FirstOrDefault();

// If the SD card is present, get the route from the SD card.
if (sdCard != null)
{
    ExternalStorageFile file = await sdCard.GetFileAsync(_sdFilePath);
    // _sdFilePath is string that having file path of file in SDCard

    // Create a stream for the route.
    Stream file = await file.OpenForReadAsync();

    // Read the route data.
    ePubView.Source = file;
 }

我在这里遇到异常 System.IO.EndOfStreamException

enter image description here

如果你想试试..这是我的项目样本link

问题:如何将我的文件作为epubView控件的源

这是正确的方法,请就此提出建议.. 感谢

2 个答案:

答案 0 :(得分:0)

虽然我没有尝试过你的方法,但我不能确切地说出错误的位置(也许SD中的文件是异步读取的,因此你得到了EndOfStream,请记住,正如在EPUB Reader网站上所说的那样 - 它正处于重大发展之中)。检查在将文件复制到ISolatedStorage之后,您是否可以使用它。
我会尝试在这种情况下首先从SD复制到内存流,如下所示:

ExternalStorageDevice sdCard = (await ExternalStorage.GetExternalStorageDevicesAsync()).FirstOrDefault();

if (sdCard != null)
{
   MemoryStream newStream = new MemoryStream();
   using (ExternalStorageFile file = await sdCard.GetFileAsync(_sdFilePath))
    using (Stream SDfile = await file.OpenForReadAsync())
      newStream = await ReadToMemory(SDfile);

   ePubView.Source = newStream;
} 

ReadToMemory:

private async Task<MemoryStream> ReadToMemory(Stream streamToRead)
{
   MemoryStream targetStream = new MemoryStream();

   const int BUFFER_SIZE = 1024;
   byte[] buf = new byte[BUFFER_SIZE];
   int bytesread = 0;
   while ((bytesread = await streamToRead.ReadAsync(buf, 0, BUFFER_SIZE)) > 0)
   {
       targetStream.Write(buf, 0, bytesread);
   }
   return targetStream;
}

也许会有所帮助。

答案 1 :(得分:0)

从ExternalStorageFile返回的流有一个错误。有两种方法可以解决它......

如果文件很小,那么您只需将流复制到MemoryStream:

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

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

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

使用示例:

ExternalStorageFile file = await device.GetFileAsync(filename); // device is an instance of ExternalStorageDevice
Stream streamOriginal = await file.OpenForReadAsync();
ExternalStorageFileWrapper streamToUse = new ExternalStorageFileWrapper(streamOriginal);