在多个线程中将 Stream 读取到 MemoryStream
我被困在一个地方。我正在从 URL 读取 flv 文件。我正在将其读入流,然后循环将此流写入 MemoryStream。当代码退出循环时,我将整个 MemoryStream 写入 ByteArray,然后将此 ByteArray 写入硬盘上的本地文件。
由于这个flv太大,在循环中处理需要花费很多时间。我正在考虑在多个线程中读取MemoryStream中的原始大流。这意味着将 Stream 分成 10 个部分,并在多个线程中将这些部分写入 MemoryStream。我该怎么做?
我附上我的一段代码。
//Get a data stream from the url
WebRequest req = WebRequest.Create(url);
WebResponse response = req.GetResponse();
using (Stream stream = response.GetResponseStream())
{
//Download in chuncks
byte[] buffer = new byte[1024];
//Get Total Size
int dataLength = (int)response.ContentLength;
//Download to memory
//Note: adjust the streams here to download directly to the hard drive
using (MemoryStream memStream = new MemoryStream())
{
while (true)
{
//Try to read the data
int bytesRead = stream.Read(buffer, 0, buffer.Length);
if (bytesRead == 0)
{
Application.DoEvents();
break;
}
else
{
//Write the downloaded data
memStream.Write(buffer, 0, bytesRead);
}
}
//Convert the downloaded stream to a byte array
byte[] downloadedData = memStream.ToArray();
}
}
任何帮助表示赞赏 谢谢
I am stuck up in a place. I am reading a flv file from a URL. I am reading this to a Stream and then writing this Stream to a MemoryStream in a loop. When the code comes out of the loop, I am writing the whole MemoryStream to a ByteArray and then writing this ByteArray to a local file on my hard disk.
As this flv is too large, it takes a lot of time to process in the loop. I am thinking of reading the original large stream in MemoryStream in multiple threads. That means dividing the Stream in say 10 parts and writing these parts to MemoryStream in multiple threads. How do I do this?
I am attaching my piece of code.
//Get a data stream from the url
WebRequest req = WebRequest.Create(url);
WebResponse response = req.GetResponse();
using (Stream stream = response.GetResponseStream())
{
//Download in chuncks
byte[] buffer = new byte[1024];
//Get Total Size
int dataLength = (int)response.ContentLength;
//Download to memory
//Note: adjust the streams here to download directly to the hard drive
using (MemoryStream memStream = new MemoryStream())
{
while (true)
{
//Try to read the data
int bytesRead = stream.Read(buffer, 0, buffer.Length);
if (bytesRead == 0)
{
Application.DoEvents();
break;
}
else
{
//Write the downloaded data
memStream.Write(buffer, 0, bytesRead);
}
}
//Convert the downloaded stream to a byte array
byte[] downloadedData = memStream.ToArray();
}
}
Any help is appreciated
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您将无法通过使用多线程来加快下载速度。这里的限制因素不是计算机处理数据的速度,而是数据来自服务器的速度。
我建议您创建一个 WebClient 而不是
WebRequest
。然后,您可以调用WebClient.DownloadDataAsync
在后台将数据下载到内存中,或调用WebClient.DownloadFileAsync
直接下载到文件。这些方法都不会加快下载速度,但会阻止您的用户界面在下载过程中无响应。
You won't be able to speed up the download by using multiple threads. The limiting factor here is not how fast your computer can process the data, but rather how fast the data comes from the server.
Rather than try to speed this up using multiple threads, I would suggest that you create a WebClient rather than
WebRequest
. You can then callWebClient.DownloadDataAsync
to download data into memory in the background, or callWebClient.DownloadFileAsync
to download directly to a file.Neither one of those will make the download any faster, but they will prevent your user interface from being non-responsive during the download.
线程在这里不会帮助你;你将会被 IO 阻塞。现在,您将有多个线程在 IO 上阻塞,而不是 1 个线程在 IO 上阻塞。事实上,在许多情况下,在多个线程上与同一资源(或并行但相关的资源)通信将降低 IO 吞吐量以及线程开销。输:失去。
另外 - 大多数流不是为线程而设计的;您将需要一些非常复杂的协调代码来确保以正确的顺序重新组装流并且不会弄乱内部状态;坦白说,这不值得。
Threads will not help you here; you are going to be blocked on IO. Rather than 1 thread blocked on IO, you will now have multiple threads blocked on IO. In fact, in many cases talking to the same resource (or parallel but related resources) on multiple threads will decrease IO throughput, plus the threading overheads. Lose : lose.
Also - most streams are not designed for threading; you would need some very complex co-ordination code to make sure you reassemble the stream in the right order and don't mess up the internal state; frankly, it isn't worth it.