将内存流拆分为 bytearray
Posted
技术标签:
【中文标题】将内存流拆分为 bytearray【英文标题】:Split up a memorystream into bytarray 【发布时间】:2012-04-27 13:20:41 【问题描述】:我试图通过将部分读入字节数组来将内存流分成块,但我认为我有一些根本性的错误。我可以读取第一个块,但是当我尝试读取内存流的其余部分时,即使有更多字节要读取,我也会使索引超出范围。似乎问题在于接收字节缓冲区的大小需要与内存流一样大。我需要将其转换为块,因为代码位于 Web 服务中。
任何人都知道这段代码有什么问题
fb.buffer 是 MemoryStream
long bytesLeft = fb.Buffer.Length;
fb.Buffer.Position = 0;
int offset =0;
int BUFF_SIZE = 8196;
while (bytesLeft > 0)
byte[] fs = new byte[BUFF_SIZE];
fb.Buffer.Read(fs, offset, BUFF_SIZE);
offset += BUFF_SIZE;
bytesLeft -= BUFF_SIZE;
【问题讨论】:
其实这里甚至不需要使用Read
;只需使用GetBuffer
,然后在循环中,Buffer.BlockCopy
将数据从后备缓冲区传输到较小的缓冲区
【参考方案1】:
offset
这里是到数组中的偏移量。这里应该为零。您还应该查看来自Read
的return 值。不保证会填满缓冲区,即使有更多数据可用。
但是,如果这是 MemoryStream
- 更好的选择可能是 ArraySegment<byte>
,它不需要重复数据。
【讨论】:
谢谢,愚蠢的错误。以前看过这个“不保证会填满缓冲区”,一直想知道这是什么意思。读取操作是某种类型的随机过程还是? @klashagelqvist 在NetworkStream
上几乎是这样。如果还没有足够的数据来填充缓冲区,但连接也没有关闭,它只会用可用数据填充缓冲区的一部分,然后返回。但我认为这种部分读取不会发生在 MemoryStream 上。
@klashagelqvist 确实,正如 CodeInChaos 所指出的,MemoryStream 可能不会在这里咬你,但这是一个实现细节。我强烈建议遵循正式的 Stream API,only 保证“none”或“some”【参考方案2】:
请看一眼this code for Stream.Read
from MSDN - 你不应该增加offset
- 它应该始终为零。当然,除非您碰巧事先知道流的确切长度(因此您将创建具有确切大小的数组)。
您还应该始终获取从Read
读取的字节数(返回值)。
如果您希望将其拆分为“块”,您的意思是您想要 n 个 8k 块吗?然后你可能想做这样的事情:
List<byte[]> chunks = new List<byte[]>();
byte chunk = new byte[BUFF_SIZE];
int bytesRead = fb.Buffer.Read(chunk, 0, BUFF_SIZE);
while(bytesRead > 0)
if(bytesRead != BUFF_SIZE)
byte[] tail = new byte[bytesRead];
Array.Copy(chunk, tail, bytesRead);
chunk = tail;
chunks.Add(chunk);
bytesRead = fb.Buffer.Read(chunk, 0, BUFF_SIZE);
请特别注意,最后一个块的长度很可能不完全是BUFF_SIZE
。
【讨论】:
以上是关于将内存流拆分为 bytearray的主要内容,如果未能解决你的问题,请参考以下文章
在流分析中将时间戳拆分为单独的列,以便在 Power BI 中进行进一步筛选