4

Windows Phone SD カードのファイルの読み取りに問題があります。ExternalStorageFile.OpenForReadAsync を使用して、有効な Stream オブジェクトを取得します。ただし、ストリームの CanSeek プロパティが true であっても、シーク操作は無視され、位置は移動されません。

    private async void ReadFileOnSDCard(ExternalStorageFile file)
    {
        Stream stream = await file.OpenForReadAsync();
          using (stream)
          {
                 long curPos= stream.Seek(100, SeekOrigin.Begin);
                 long pos = stream.Position;

// curPos と pos の両方が 0 です。

4

3 に答える 3

0

ファイルが小さい場合は、ストリームを単に 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

于 2013-12-30T07:25:03.697 に答える
0

Windows Phone で予約されている拡張子のファイルを読んでいると思います。残念ながら、Windows Phone の SD カードからそれらを読み取ることはできません。これらの予約済みの拡張子に分類されるファイルを読んでいる場合、Windows Phone は単純にそれらを無視します。

これらの予約された拡張子を読んでいないと仮定すると、次の 2 つの手順に従って問題を解決できます。

1/ 最初 <Capability Name="ID_CAP_REMOVABLE_STORAGE" />に、WMAppManifest.xml に既に追加されているかどうかを確認します

2/ 登録していない場合は、.gpx などのファイル関連付け拡張子を登録します。

<FileTypeAssociation TaskID="_default" Name="GPX" NavUriFragment="fileToken=%s">
  <Logos>
    <Logo Size="small" IsRelative="true">Assets/Route_Mapper_Logo33x33.png</Logo>
    <Logo Size="medium" IsRelative="true">Assets/Route_Mapper_Logo69x69.png</Logo>
    <Logo Size="large" IsRelative="true">Assets/Route_Mapper_Logo176x176.png</Logo>
  </Logos>
  <SupportedFileTypes>
    <FileType ContentType="application/gpx">.gpx</FileType>
  </SupportedFileTypes>
</FileTypeAssociation>
于 2013-05-11T23:23:36.813 に答える