โหลดไฟล์จาก SDCard

ฉันรวมโปรแกรมอ่าน (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

ป้อนคำอธิบายรูปภาพที่นี่

หากคุณต้องการลอง.. นี่คือลิงก์ตัวอย่างโครงการของฉัน

คำถาม : ฉันจะให้ไฟล์ของฉันเป็นแหล่งควบคุม epubView ได้อย่างไร

นี่เป็นวิธีที่ถูกต้องหรือไม่กรุณาแนะนำเกี่ยวกับเรื่องนี้ด้วย.. ขอบคุณ


person Kumar    schedule 28.01.2014    source แหล่งที่มา
comment
แล้วมันได้ผลเหรอ? คุณมีปัญหาอะไรเป็นพิเศษหรือไม่?   -  person richzilla    schedule 28.01.2014
comment
ดูโอเค อย่าลืมเพิ่ม FileTypeAssociation ในรายการของคุณ   -  person Romasz    schedule 28.01.2014
comment
ฉันเพิ่ม FileTypeAssociation ใน Manifest และฉันเกือบลืมพูดถึงข้อยกเว้น .. ฉันแก้ไขคำถามแล้ว   -  person Kumar    schedule 28.01.2014
comment
ฉันเพิ่มตัวอย่างของโครงการที่นี่ [sdrv.ms/1b0pXWv]   -  person Kumar    schedule 28.01.2014


คำตอบ (2)


แม้ว่าฉันไม่ได้ลองใช้แนวทางของคุณ และฉันไม่สามารถบอกได้อย่างแน่ชัดว่ามีข้อผิดพลาดเกิดขึ้นที่ใด (บางทีไฟล์จาก 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;
}

บางทีมันอาจจะช่วยได้

person Romasz    schedule 28.01.2014
comment
@Romsaz มันใช้งานได้เป็นครั้งแรก หลังจากนั้นไม่ทำงาน .. ให้ค่าว่าง นี่คือลิงค์จาก MSDN [social.msdn.microsoft.com/Forums/wpapps/en-US/ ] ขอบคุณที่ให้ความหวังฉันในการเริ่มต้น.. - person Kumar; 30.01.2014
comment
@kumar รหัสของฉันเขียนโดยไม่ได้ตรวจสอบ - ฉันดีใจที่มันใช้งานได้ คุณได้โมฆะมาจากไหน? และคุณหมายถึงอะไรว่าไม่ทำงานต่อไป - เมื่อใด? - person Romasz; 30.01.2014

มีข้อบกพร่องกับสตรีมที่ส่งคืนจาก ExternalStorageFile มีสองทางเลือกในการหลีกเลี่ยง ...

หากไฟล์มีขนาดเล็ก คุณก็สามารถคัดลอกสตรีมไปยัง MemoryStream ได้:

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

อย่างไรก็ตาม หากไฟล์มีขนาดใหญ่เกินไป คุณจะประสบปัญหาด้านหน่วยความจำ ดังนั้นจึงสามารถใช้คลาส wrapper สตรีมต่อไปนี้เพื่อแก้ไขจุดบกพร่องของ 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);
person Gavin    schedule 25.02.2014
comment
ขออภัยที่ตอบช้ามาก & ใช่ สำหรับบางไฟล์โปรเจ็กต์ของฉันไม่ทำงาน ฉันเพิ่มโครงการของคุณลงในโซลูชันของฉัน & จริงๆ แล้วฉันไม่เข้าใจว่าจะใช้รหัสของคุณใน ExternalStorageFileWrapper class ได้อย่างไร คุณช่วยกรุณาแนะนำสิ่งที่ต้องทำหลังจากได้รับสตรีมไฟล์ ExternalStorageFileWrapper EFW = new ExternalStorageFileWrapper(s); - person Kumar; 05.03.2014
comment
มีตัวอย่างโค้ดที่ด้านล่างของ github.com/gavinharriss/ExternalStorageFileWrapper-wp8 - ทำอย่างนั้น ช่วยคุณ? ExternalStorageFileWrapper ใช้อินเทอร์เฟซ Stream ดังนั้นจึงสามารถใช้แทนสตรีมดั้งเดิมได้ - person Gavin; 05.03.2014
comment
ใช่.. ฉันใช้รหัสนั้น ดูเหมือนว่ารหัสของฉันจะมีปัญหาหลังจากได้รับไฟล์จาก SDcard ไม่ใช่ปัญหากับ ExternalStorageFileWrapper ของคุณ ฉันขอตรวจสอบความเป็นไปได้เพิ่มเติม จะแจ้งสถานะผลที่นี่ครับ ขอบคุณ - person Kumar; 06.03.2014