如何从 .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?的主要内容,如果未能解决你的问题,请参考以下文章