将一个流的内容复制到另一个流的最佳方法是什么?有标准的实用方法吗?
当前回答
不幸的是,没有真正简单的解决办法。你可以尝试这样做:
Stream s1, s2;
byte[] buffer = new byte[4096];
int bytesRead = 0;
while (bytesRead = s1.Read(buffer, 0, buffer.Length) > 0) s2.Write(buffer, 0, bytesRead);
s1.Close(); s2.Close();
但问题是,如果没有什么可读取的,Stream类的不同实现可能会有不同的行为。从本地硬盘读取文件的流可能会阻塞,直到读操作从磁盘读取了足够的数据来填充缓冲区,并且只有在到达文件末尾时才返回较少的数据。另一方面,从网络读取的流可能返回更少的数据,即使有更多的数据需要接收。
在使用通用解决方案之前,一定要检查您正在使用的特定流类的文档。
其他回答
由于没有一个答案涉及从一个流复制到另一个流的异步方式,这里是我在端口转发应用程序中成功使用的一种模式,它将数据从一个网络流复制到另一个网络流。它缺乏异常处理来强调模式。
const int BUFFER_SIZE = 4096;
static byte[] bufferForRead = new byte[BUFFER_SIZE];
static byte[] bufferForWrite = new byte[BUFFER_SIZE];
static Stream sourceStream = new MemoryStream();
static Stream destinationStream = new MemoryStream();
static void Main(string[] args)
{
// Initial read from source stream
sourceStream.BeginRead(bufferForRead, 0, BUFFER_SIZE, BeginReadCallback, null);
}
private static void BeginReadCallback(IAsyncResult asyncRes)
{
// Finish reading from source stream
int bytesRead = sourceStream.EndRead(asyncRes);
// Make a copy of the buffer as we'll start another read immediately
Array.Copy(bufferForRead, 0, bufferForWrite, 0, bytesRead);
// Write copied buffer to destination stream
destinationStream.BeginWrite(bufferForWrite, 0, bytesRead, BeginWriteCallback, null);
// Start the next read (looks like async recursion I guess)
sourceStream.BeginRead(bufferForRead, 0, BUFFER_SIZE, BeginReadCallback, null);
}
private static void BeginWriteCallback(IAsyncResult asyncRes)
{
// Finish writing to destination stream
destinationStream.EndWrite(asyncRes);
}
区分“CopyStream”实现的基本问题是:
读取缓冲区的大小 写入的大小 我们是否可以使用多个线程(在读取时写入)。
这些问题的答案导致了CopyStream的巨大不同的实现,这取决于您拥有的流的类型和您试图优化的内容。“最佳”实现甚至需要知道流正在读取和写入的具体硬件。
对于。net 3.5和尝试之前:
MemoryStream1.WriteTo(MemoryStream2);
不幸的是,没有真正简单的解决办法。你可以尝试这样做:
Stream s1, s2;
byte[] buffer = new byte[4096];
int bytesRead = 0;
while (bytesRead = s1.Read(buffer, 0, buffer.Length) > 0) s2.Write(buffer, 0, bytesRead);
s1.Close(); s2.Close();
但问题是,如果没有什么可读取的,Stream类的不同实现可能会有不同的行为。从本地硬盘读取文件的流可能会阻塞,直到读操作从磁盘读取了足够的数据来填充缓冲区,并且只有在到达文件末尾时才返回较少的数据。另一方面,从网络读取的流可能返回更少的数据,即使有更多的数据需要接收。
在使用通用解决方案之前,一定要检查您正在使用的特定流类的文档。
. net Framework 4引入了新的系统流类的CopyTo方法。IO命名空间。使用此方法,我们可以将一个流复制到不同流类的另一个流。
这里有一个例子。
FileStream objFileStream = File.Open(Server.MapPath("TextFile.txt"), FileMode.Open);
Response.Write(string.Format("FileStream Content length: {0}", objFileStream.Length.ToString()));
MemoryStream objMemoryStream = new MemoryStream();
// Copy File Stream to Memory Stream using CopyTo method
objFileStream.CopyTo(objMemoryStream);
Response.Write("<br/><br/>");
Response.Write(string.Format("MemoryStream Content length: {0}", objMemoryStream.Length.ToString()));
Response.Write("<br/><br/>");
推荐文章
- 防止在ASP中缓存。NET MVC中使用属性的特定操作
- 转换为值类型'Int32'失败,因为物化值为空
- c#中有任何连接字符串解析器吗?
- 在Linq中转换int到字符串到实体的问题
- 是否可以动态编译和执行c#代码片段?
- 创建自定义MSBuild任务时,如何从c#代码获取当前项目目录?
- c#和Java的主要区别是什么?
- 在c#中创建一个特定时区的DateTime
- .NET中的属性是什么?
- csproj文件中的“Service Include”是干什么用的?
- 如何使用try catch进行异常处理是最佳实践
- 替换字符串中第一次出现的模式
- .NET中字节的字面后缀?
- 如何处理AccessViolationException
- c#忽略证书错误?