【问题标题】:The stream was not openned for reading流未打开以供阅读
【发布时间】:2020-06-17 21:28:11
【问题描述】:

我正在从云端下载一个 PowerPoint 文件。为了限制下载文件的多次调用,我使用MemoryCache 对其进行缓存。下面的代码第一次运行正常,但第一次运行后抛出异常:

“未打开流进行读取。”

下面是我正在使用的代码:

var cache = MemoryCache.Default;
var memoryStream = new MemoryStream();
if(cache.contains(key)) {
    memoryStream = (MemoryStream)cache.Get(key);
} else {
    var file = getFile();
    cache.Add(key, file);
    memoryStream = (MemoryStream)cache.Get(key);
}

using(memoryStream) {
    Open file and do manupulation then save the file in cloud.
}

更新代码:

var cache = MemoryCache.Default;
byte[] data = (byte[])cache.Get(key);
if(data == null)
{
    data_stream = getData(); // get memorystream
    cache.Add(key, data_stream.ToArray(), new CacheItemPolicy());
    data = (byte[])cache.Get(key);
}

using(Stream outputStream = new MemoryStream(decktemplate)) {
    Open file and do manupulation then save the file in cloud.
}

仍然收到以下错误:“算术运算导致溢出。”

下面是堆栈树:

   at MS.Internal.IO.Zip.ZipIOExtraField.ParseRecord(BinaryReader reader, ZipIOZip64ExtraFieldUsage zip64extraFieldUsage, UInt16 expectedExtraFieldSize)
   at MS.Internal.IO.Zip.ZipIOCentralDirectoryFileHeader.ParseRecord(BinaryReader reader, Encoding encoding)
   at MS.Internal.IO.Zip.ZipIOCentralDirectoryBlock.ParseRecord(BinaryReader reader, Int64 centralDirectoryOffset, Int32 centralDirectoryCount, Int64 expectedCentralDirectorySize)
   at MS.Internal.IO.Zip.ZipIOCentralDirectoryBlock.SeekableLoad(ZipIOBlockManager blockManager)
   at MS.Internal.IO.Zip.ZipIOBlockManager.get_CentralDirectoryBlock()
   at MS.Internal.IO.Zip.ZipArchive.GetFiles()
   at System.IO.Packaging.ZipPackage.ContentTypeHelper..ctor(ZipArchive zipArchive, IgnoredItemHelper ignoredItemHelper)
   at System.IO.Packaging.ZipPackage..ctor(Stream s, FileMode mode, FileAccess access, Boolean streaming)
   at System.IO.Packaging.Package.Open(Stream stream, FileMode packageMode, FileAccess packageAccess, Boolean streaming)
   at DocumentFormat.OpenXml.Packaging.OpenXmlPackage.OpenCore(Stream stream, Boolean readWriteMode)
   at DocumentFormat.OpenXml.Packaging.PresentationDocument.Open(Stream stream, Boolean isEditable, OpenSettings openSettings)
   at DocumentFormat.OpenXml.Packaging.PresentationDocument.Open(Stream stream, Boolean isEditable)

【问题讨论】:

  • 因为它在 using 块中,所以它被处理掉了。此外,您可能需要在使用后将其倒带(它不是 VHS,但它确实有一个指向它所在位置的内部指针)。另外,你会一直在内存中缓存吗(序列化流在概念上很困难)?

标签: c# .net caching memorycache


【解决方案1】:

MemoryStream 作为对象 存储在缓存中是一个非常糟糕的主意,因为多个线程可能同时访问它。最好将 payload 存储为byte[]ArraySegment<byte>,并使用它为每个调用者创建一个不同 MemoryStream。否则,你会经常被自己绊倒:

byte[] payload = (byte[])cache.Get(key);
if (payload is null)
{
    payload = GetFilePayload();
    cache.Add(key, payload);
}
using(var memoryStream = new MemoryStream(payload, writable: false))
{
    // ...
}

【讨论】:

  • 我仍然收到同样的错误:“未打开流以供阅读。”将 MemoryStream 的可写标记为 true 时,会出现异常:“算术运算导致溢出”
  • 这听起来不像是来自显示的代码;你有堆栈跟踪吗?
  • @ManjurAnsari 具体来说,第一个听起来像是您的 getFile 方法中的错误文件处理代码,而第二个听起来像是“and do manupulation”代码中的一些不正确的数据处理代码。您还没有向我们展示其中任何一个。
  • getFile 方法正在返回 MemoryStream。实际上文件是.pptx。在操作过程中,我打开了 .pptx 文件和额外的幻灯片,并将最终的幻灯片上传到云端。
  • @ManjurAnsari 该声明中没有任何内容让我认为代码是正确的
猜你喜欢
  • 2013-11-17
  • 1970-01-01
  • 2012-04-22
  • 1970-01-01
  • 1970-01-01
  • 2014-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多