Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从.NET中的流中获取MemoryStream?_C#_.net_File Io_Stream_Memorystream - Fatal编程技术网

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

C# 如何从.NET中的流中获取MemoryStream?,c#,.net,file-io,stream,memorystream,C#,.net,File Io,Stream,Memorystream,我有以下构造函数方法,可以从文件路径打开MemoryStream: MemoryStream _ms; public MyClass(string filePath) { byte[] docBytes = File.ReadAllBytes(filePath); _ms = new MemoryStream(); _ms.Write(docBytes, 0, docBytes.Length); } 我需要将其更改为接受流,而不是文件路径。从流对象获取内存流的最简单/

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

MemoryStream _ms;

public MyClass(string filePath)
{
    byte[] docBytes = File.ReadAllBytes(filePath);
    _ms = new MemoryStream();
    _ms.Write(docBytes, 0, docBytes.Length);
}
我需要将其更改为接受
,而不是文件路径。从
对象获取
内存流
的最简单/最有效的方法是什么?


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

如果您要修改类以接受流而不是文件名,请不要麻烦转换为MemoryStream。让底层流处理以下操作:

public class MyClass
{ 
    Stream _s;

    public MyClass(Stream s) { _s = s; }
}
但如果内部操作确实需要MemoryStream,则必须将数据从源流复制到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);
    }
}

您必须将流对象中的所有数据读入
字节[]
缓冲区,然后通过其构造函数将其传递到
内存流。最好更具体地说明您正在使用的流对象的类型
Stream
非常通用,可能无法实现
Length
属性,这在读取数据时非常有用

以下是一些代码:

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

    _ms = new MemoryStream(inputBuffer);
}
如果
对象未实现
长度
属性,则必须实现如下内容:

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;
}

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

    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);
        }
    }
在.NET 4中,您可以使用来复制流,而不是其他答案中列出的自制方法

MemoryStream _ms;

public MyClass(Stream sourceStream)

    _ms = new MemoryStream();
    sourceStream.CopyTo(_ms);
}
使用以下命令:

var memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
这将
转换为
内存流

,您只需执行以下操作:

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

流位置为0,可以使用。

一旦有了流,为什么还要麻烦将其转换为MemoryStream?你不能直接处理流吗?由于其他依赖关系,我需要一个MemoryStream。在某些情况下,处理流的性能差会导致MemoryStream更高效。就像我这里的问题:我想这是while行末尾的
>0
?@fearofahackplanet-正确。我有点高兴。已修复。似乎缺少一个右括号。应该是
while((read=input.read(buffer,0,buffer.Length))>0)
可能要添加
output.Position=0作为最后一行,否则您需要记住稍后重置它。请确保首先设置sourceStream.Position=0;您需要设置_ms.Position=0;这是最干净、最优雅的解决方案。这根本不能回答问题!
var memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
var ms = new MemoryStream(File.ReadAllBytes(filePath));