【问题标题】:How to get a MemoryStream from a Stream in .NET?如何从 .NET 中的流中获取 MemoryStream?
【发布时间】:2011-03-13 20:46:54
【问题描述】:

我有以下构造方法,它从文件路径打开MemoryStream

MemoryStream _ms;

public MyClass(string filePath)
{
    byte[] docBytes = File.ReadAllBytes(filePath);
    _ms = new MemoryStream();
    _ms.Write(docBytes, 0, docBytes.Length);
}

我需要将其更改为接受Stream 而不是文件路径。从Stream 对象获取MemoryStream 的最简单/最有效的方法是什么?

【问题讨论】:

  • 一旦你有了 Stream,为什么还要把它转换成 MemoryStream?您不能直接使用 Stream 吗?
  • 由于其他依赖关系,我需要一个 MemoryStream。
  • 在某些情况下,使用 Streams 的性能不佳会导致 MemoryStream 更高效。喜欢我的问题:stackoverflow.com/questions/50399481/…

标签: c# .net file-io stream memorystream


【解决方案1】:

在 .NET 4 中,您可以使用 Stream.CopyTo 复制流,而不是其他答案中列出的自制方法。

MemoryStream _ms;

public MyClass(Stream sourceStream)

    _ms = new MemoryStream();
    sourceStream.CopyTo(_ms);
}

【讨论】:

  • 确保首先设置 sourceStream.Position = 0;
  • 你需要设置 _ms.Position = 0;在使用它之前。
【解决方案2】:

使用这个:

var memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);

这会将Stream 转换为MemoryStream

【讨论】:

    【解决方案3】:

    如果您正在修改您的类以接受 Stream 而不是文件名,请不要费心转换为 MemoryStream。让底层 Stream 处理操作:

    public class MyClass
    { 
        Stream _s;
    
        public MyClass(Stream s) { _s = s; }
    }
    

    但如果您确实需要 MemoryStream 进行内部操作,则必须将数据从源 Stream 复制到 MemoryStream 中:

    public MyClass(Stream stream)
    {
        _ms = new MemoryStream();
        CopyStream(stream, _ms);
    }
    
    // Merged From linked CopyStream below and Jon Skeet's ReadFully example
    public static void CopyStream(Stream input, Stream output)
    {
        byte[] buffer = new byte[16*1024];
        int read;
        while((read = input.Read (buffer, 0, buffer.Length)) > 0)
        {
            output.Write (buffer, 0, read);
        }
    }
    

    【讨论】:

    • 我假设在 while 行的末尾是 > 0
    • @fearofawhackplanet - 正确。我得到了一点删除高兴。固定。
    • 好像少了一个右括号。应该是while((read = input.Read(buffer,0,buffer.Length)) > 0)
    • 可能要添加output.Position = 0; 作为最后一行,否则您需要记住稍后重新设置它。
    【解决方案4】:

    你可以这样做:

    var ms = new MemoryStream(File.ReadAllBytes(filePath));
    

    流位置为 0,可以使用。

    【讨论】:

    • 这是最干净、最优雅的解决方案。
    • 这根本不能回答问题!
    【解决方案5】:

    您必须将 Stream 对象中的所有数据读入 byte[] 缓冲区,然后通过其构造函数将其传递给 MemoryStream。最好更具体地了解您正在使用的流对象的类型。 Stream 非常通用,可能没有实现Length 属性,这在读入数据时相当有用。

    这里有一些代码给你:

    public MyClass(Stream inputStream) {
        byte[] inputBuffer = new byte[inputStream.Length];
        inputStream.Read(inputBuffer, 0, inputBuffer.Length);
    
        _ms = new MemoryStream(inputBuffer);
    }
    

    如果Stream 对象没有实现Length 属性,您将不得不实现如下内容:

    public MyClass(Stream inputStream) {
        MemoryStream outputStream = new MemoryStream();
    
        byte[] inputBuffer = new byte[65535];
        int readAmount;
        while((readAmount = inputStream.Read(inputBuffer, 0, inputBuffer.Length)) > 0)
            outputStream.Write(inputBuffer, 0, readAmount);
    
        _ms = outputStream;
    }
    

    【讨论】:

      【解决方案6】:

      我使用这种扩展方法的组合:

          public static Stream Copy(this Stream source)
          {
              if (source == null)
                  return null;
      
              long originalPosition = -1;
      
              if (source.CanSeek)
                  originalPosition = source.Position;
      
              MemoryStream ms = new MemoryStream();
      
              try
              {
                  Copy(source, ms);
      
                  if (originalPosition > -1)
                      ms.Seek(originalPosition, SeekOrigin.Begin);
                  else
                      ms.Seek(0, SeekOrigin.Begin);
      
                  return ms;
              }
              catch
              {
                  ms.Dispose();
                  throw;
              }
          }
      
          public static void Copy(this Stream source, Stream target)
          {
              if (source == null)
                  throw new ArgumentNullException("source");
              if (target == null)
                  throw new ArgumentNullException("target");
      
              long originalSourcePosition = -1;
              int count = 0;
              byte[] buffer = new byte[0x1000];
      
              if (source.CanSeek)
              {
                  originalSourcePosition = source.Position;
                  source.Seek(0, SeekOrigin.Begin);
              }
      
              while ((count = source.Read(buffer, 0, buffer.Length)) > 0)
                  target.Write(buffer, 0, count);
      
              if (originalSourcePosition > -1)
              {
                  source.Seek(originalSourcePosition, SeekOrigin.Begin);
              }
          }
      

      【讨论】:

        【解决方案7】:

        How do I copy the contents of one stream to another?

        看到了。接受流并复制到内存。你不应该只使用.Length Stream,因为它不一定在每个具体的流中都实现。

        【讨论】:

          【解决方案8】:
          public static void Do(Stream in)
          {
              _ms = new MemoryStream();
              byte[] buffer = new byte[65536];
              while ((int read = input.Read(buffer, 0, buffer.Length))>=0)
                  _ms.Write (buffer, 0, read);
          }
          

          【讨论】:

            【解决方案9】:
            byte[] fileData = null;
            using (var binaryReader = new BinaryReader(Request.Files[0].InputStream))
            {
                fileData = binaryReader.ReadBytes(Request.Files[0].ContentLength);
            }
            

            【讨论】:

              猜你喜欢
              • 2010-09-09
              • 1970-01-01
              • 2023-01-17
              • 2020-09-19
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-07-20
              • 2012-07-08
              相关资源
              最近更新 更多