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