【问题标题】:Composite Stream Wrapper providing partial MemoryStream and full original StreamComposite Stream Wrapper 提供部分 MemoryStream 和完整的原始 Stream
【发布时间】:2013-12-30 09:21:28
【问题描述】:

有谁知道一种复合流解决方案,它将流的第一部分预加载到 MemoryStream 中,并将其余部分保留为原始流,当需要后续部分时需要访问该原始流?

我应该想象一些包装类将实现 Stream 接口,并根据访问的部分透明地在两个流之间进行访问。

我希望这是以前有人可能已经解决的解决方案,也许是为了优化读取大型 FileStream 的性能。

在我的情况下,我正在尝试解决 Windows Phone 8 中从 SD 卡读取大文件的错误。此答案中提供了我试图解决的问题的更多详细信息: https://stackoverflow.com/a/17355068/250254

【问题讨论】:

  • @RussCam - 谢谢你,非常感谢!与我的流重叠的问题不完全相同,但我会挑选一下,看看是否有什么我可以适应的。
  • 我认为这不是解决问题的正确方法...您打算将多少数据加载到 MemoryStream 中?如果我正确理解了这个问题,那么对于 long 的低 32 位中的任何偏移都会出现 Seek 问题,这意味着您需要将 4GB 的数据加载到内存中......
  • @ThomasLevesque - 试验似乎在 400408 位置附近问题可能会消失。所以大约 0.4 mb 需要保存在内存流中。仍在试验,所以我可能是错的!

标签: c# stream wrapper memorystream stream-wrapper


【解决方案1】:

没有任何合理的方法可以使用 MemoryStream 来解决该错误,您首先会遇到 OutOfMemoryException。让我们把注意力集中在 bug 上,我会稍微简化一下代码以使其可读:

DistanceToMove = (offset & 0xffffffff00000000L) >> 32;
DistanceToMoveHigh = offset & 0xffffffffL;
SetFilePointer(this.m_handle, lDistanceToMove, ref lDistanceToMoveHigh, begin);

Microsoft 程序员不小心交换了低值和高值。好吧,您也可以撤消该错误。自己交换它们,这样 bug 就会按照你想要的方式交换它们:

public static void SeekBugWorkaround(Stream stream, long offset, SeekOrigin origin) {
    ulong uoffset = (ulong)offset;
    ulong fix = ((uoffset & 0xffffffffL) << 32) | ((uoffset & 0xffffffff00000000L) >> 32);
    stream.Seek((long)fix, origin);
}

如果需要说,它显然是,你必须指望微软最终修复这个错误。很难预测什么时候会在下一个版本上赌博。有一些几率您可以自动检测到这一点,尽管微软将要做什么并不明显,因为这个错误非常严重。 Seek() 的返回值以及 Position 属性的返回值存在相同的错误。因此,寻求位置 1 并验证您是否获得了 1 的回报。

【讨论】:

  • 哎呀,这听起来像是一场向前兼容的噩梦!
  • @CoryNelson - 应该能够检查 Windows Phone 操作系统版本,我希望在以后的版本中绕过修复。
  • @hans-passant - 谢谢你 - 非常感谢。我将在接下来的一两天内进行一场比赛,看看我是否可以让它发挥作用(这是我做的一个非付费项目)。我想我会实现一个包装流类,使用你的逻辑覆盖 Seek 方法。
  • 我想知道这样的错误是如何在不被发现的情况下进入生产环境的……他们在 MS 没有单元测试吗?
  • 对于任何想要可以放入他们的解决方案的流包装器的人 - github.com/gavinharriss/ExternalStorageFileWrapper-wp8
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-29
  • 1970-01-01
  • 2013-12-17
  • 1970-01-01
  • 2015-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多