我在读取Windows Phone SD卡上的文件时遇到问题。我使用ExternalStorageFile.OpenForReadAsync获取有效的Stream对象。然而,尽管流CanSeek属性为真,任何查找操作都将被忽略,并且位置不会移动;
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
发布于 2013-06-28 07:46:44
我也在和同样的问题作斗争。Seek确实在Microsoft.Phone.Storage.NativeFileStream中被破坏了,这是SD卡上文件的流类型。最后,我用ILspy查看了这个类,就是这样:
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,
...
}和函数SetFilePointer:http://msdn.microsoft.com/en-us/library/windows/desktop/aa365541%28v=vs.85%29.aspx
要使寻道工作,偏移值应为长度的较高32位。
发布于 2013-05-12 07:23:37
我猜您正在读取一个扩展名为reserved by Windows Phone的文件。不幸的是,你不能从Windows Phone上的SD卡中读取它们。如果你正在阅读的文件属于这些保留的扩展名,Windows Phone只需忽略它们即可。
假设你没有阅读这些保留的扩展,你可以按照以下两个步骤来解决你的问题。
1/首先检查您是否已经在WMAppManifest.xml中添加了<Capability Name="ID_CAP_REMOVABLE_STORAGE" />
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-12-30 15:25:04
如果文件很小,那么您可以简单地将流复制到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
https://stackoverflow.com/questions/15752463
复制相似问题