如何从 .NET 中的流中获取 MemoryStream?

Posted

技术标签:

【中文标题】如何从 .NET 中的流中获取 MemoryStream?【英文标题】:How to get a MemoryStream from a Stream in .NET? 【发布时间】: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 更高效。喜欢我的问题:***.com/questions/50399481/… 【参考方案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);

【讨论】:

以上是关于如何从 .NET 中的流中获取 MemoryStream?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 iOS 中的流中接收数据(swift)

如何从我的流中获取数据并使用它?

如何从使用 Futures/async/await 的流中正确生成?

Azure媒体服务实时流中的流键

如何从已排序的流中最好地构建持久二叉树

Python 3 从互联网广播流中获取歌曲名称