2013-04-01 1 views
4

J'ai des problèmes pour lire le fichier sur la carte SD de Windows Phone. J'obtiens l'objet Stream valide en utilisant ExternalStorageFile.OpenForReadAsync. Cependant, toute opération de recherche est ignorée et la position n'est pas déplacée bien que la propriété CanSeek du flux soit vraie;Problème lors de la lecture du fichier sur Windows Phone 8 Carte SD

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

// les deux CURPOS et pos sont 0.

+0

double possible de [fournir partielle composite flux Wrapper MemoryStream et le flux original complet] (http://stackoverflow.com/questions/20836625/composite-stream-wrapper-providing-partial-memorystream-and-full-original-stream) –

Répondre

0

Je suppose que vous lisez un fichier avec l'extension qui est reserved by Windows Phone. Malheureusement, vous ne pouvez pas les lire depuis la carte SD sur Windows Phone. Si vous lisez un fichier tombe dans ces extensions réservées, Windows Phone simplement simplement les ignorer.

Supposons que vous ne lisez pas ces extensions réservées, vous pouvez suivre ces deux étapes pour résoudre votre problème.

1/Vérifiez d'abord si vous avez déjà ajouté <Capability Name="ID_CAP_REMOVABLE_STORAGE" /> à votre WMAppManifest.xml

2/Inscrivez-vous une extension d'association de fichiers si vous ne l'avez pas, par exemple .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> 
2

Je me battais avec le même problème. Seek est en effet cassé dans Microsoft.Phone.Storage.NativeFileStream, qui est le type de flux pour les fichiers sur la carte SD. En fin de compte, je regardais la classe avec ILspy, et voici:

public override long Seek(long offset, System.IO.SeekOrigin origin) 
{ 
    ... 
    uint num = (uint)((ulong)(offset & -4294967296L) >> 32); 
    uint num2 = (uint)(offset & (long)((ulong)-1)); 
    uint num3 = NativeFileStream.SetFilePointer(this.m_handle, num, ref num2, 
    ... 
} 

et la fonction SetFilePointer: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365541%28v=vs.85%29.aspx

Pour chercher du travail, valeur de décalage devrait être en 32bits plus de long.

+0

Je pense que j'ai moi-même rencontré le même problème. Alors as-tu simplement tamponné tes fichiers avec les ordures/0 pour que tu puisses commencer ton offset beaucoup plus profondément dans le fichier? Un niveau un peu plus bas que ce que j'ai l'habitude de m'excuser si ma formulation est un peu grossière. – Gavin

+0

Je me demande s'il est possible d'hériter de Microsoft.Phone.Storage.NativeFileStream et remplacer la méthode Seek? – Gavin

+0

Instance de NativeFileStream est ce que vous obtenez lorsque vous ouvrez un fichier sur la carte SD, donc l'annulation n'est pas une solution, je pense. J'ai une classe de wrapper Stream simple avec Seek override, où juste je décale la valeur de décalage passée à plus haut 32bits avant d'appeler la méthode Seek de sous-jacent. – Ales

0

Si le fichier est petit, vous pouvez simplement copier le flux dans un MemoryStream. Je l'ai testé et il fonctionne:

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

Cependant, si le fichier est trop volumineux, vous tomberez pour des problèmes de mémoire de sorte que la classe enveloppe de flux suivant peut être utilisé pour corriger le bug de Microsoft (bien que dans les versions futures de windows Phone vous devrez désactiver ce correctif une fois que le bug a été corrigé):

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

est disponible ici pour déposer à votre projet: https://github.com/gavinharriss/ExternalStorageFileWrapper-wp8

Questions connexes