80

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

MemoryStream _ms;

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

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

4

9 回答 9

219

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

MemoryStream _ms;

public MyClass(Stream sourceStream)

    _ms = new MemoryStream();
    sourceStream.CopyTo(_ms);
}
于 2010-07-09T13:24:01.070 回答
62

用这个:

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

这将转换StreamMemoryStream.

于 2015-09-28T10:07:55.243 回答
32

如果您正在修改您的类以接受 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);
    }
}
于 2010-07-09T12:58:26.433 回答
5

你可以简单地做:

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

流位置为 0 并且可以使用。

于 2018-11-02T11:23:08.943 回答
3

您必须将 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;
}
于 2010-07-09T13:01:50.437 回答
3

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

    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);
        }
    }
于 2010-07-09T13:10:05.130 回答
2

如何将一个流的内容复制到另一个流?

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

于 2010-07-09T12:57:22.680 回答
2
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);
}
于 2010-07-09T13:00:45.100 回答
0
byte[] fileData = null;
using (var binaryReader = new BinaryReader(Request.Files[0].InputStream))
{
    fileData = binaryReader.ReadBytes(Request.Files[0].ContentLength);
}
于 2014-01-14T20:44:26.310 回答