设置流中的偏移量
它在这里 msdn.microsoft.com/en-us/library/system.io.stream.read.aspx 说 Stream.Read
和 Stream.Write
方法都前进流中的位置/偏移量会自动执行,为什么这里的示例是 http://msdn.microsoft.com/en-us/library/system.io.stream.read.aspx 和 http://msdn.microsoft.com/en-us/library/system.io.filestream.read.aspx 手动更改偏移量?
如果您知道流的大小,是否仅在循环中设置偏移量;如果您不知道大小并使用缓冲区,则将其设置为 0?
// Now read s into a byte buffer.
byte[] bytes = new byte[s.Length];
int numBytesToRead = (int) s.Length;
int numBytesRead = 0;
while (numBytesToRead > 0)
{
// Read may return anything from 0 to 10.
int n = s.Read(bytes, numBytesRead, 10);
// The end of the file is reached.
if (n == 0)
{
break;
}
numBytesRead += n;
numBytesToRead -= n;
}
和
using (GZipStream stream = new GZipStream(new MemoryStream(gzip), CompressionMode.Decompress))
{
const int size = 4096;
byte[] buffer = new byte[size];
using (MemoryStream memory = new MemoryStream())
{
int count = 0;
do
{
count = stream.Read(buffer, 0, size);
if (count > 0)
{
memory.Write(buffer, 0, count);
}
}
while (count > 0);
return memory.ToArray();
}
}
It says here msdn.microsoft.com/en-us/library/system.io.stream.read.aspx that the Stream.Read
and Stream.Write
methods both advance the position/offset in the stream automatically so why is the examples here http://msdn.microsoft.com/en-us/library/system.io.stream.read.aspx and http://msdn.microsoft.com/en-us/library/system.io.filestream.read.aspx manually changing the offset?
Do you only set the offset in a loop if you know the size of the stream and set it to 0 if you don't know the size and using a buffer?
// Now read s into a byte buffer.
byte[] bytes = new byte[s.Length];
int numBytesToRead = (int) s.Length;
int numBytesRead = 0;
while (numBytesToRead > 0)
{
// Read may return anything from 0 to 10.
int n = s.Read(bytes, numBytesRead, 10);
// The end of the file is reached.
if (n == 0)
{
break;
}
numBytesRead += n;
numBytesToRead -= n;
}
and
using (GZipStream stream = new GZipStream(new MemoryStream(gzip), CompressionMode.Decompress))
{
const int size = 4096;
byte[] buffer = new byte[size];
using (MemoryStream memory = new MemoryStream())
{
int count = 0;
do
{
count = stream.Read(buffer, 0, size);
if (count > 0)
{
memory.Write(buffer, 0, count);
}
}
while (count > 0);
return memory.ToArray();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(2)
编辑(针对已编辑的问题):
在您粘贴到问题中的所有代码片段中,我都没有看到设置任何流偏移量。
我认为您错误地计算了要读取的字节与接收到的字节。该协议可能看起来很有趣(为什么您收到的字节数少于请求的字节数?),但是当您考虑到您可能正在从面向高延迟数据包的源(例如:网络套接字)读取数据时,它就有意义了。
您可能会在一次突发中接收 6 个字符(来自 TCP 数据包),而在下一次读取时(当下一个数据包到达时)仅收到剩余的 4 个字符。
编辑响应评论中的链接示例:
using (GZipStream stream = new GZipStream(new MemoryStream(gzip), CompressionMode.Decompress))
{
// ... snip
count = stream.Read(buffer, 0, size);
if (count > 0)
{
memory.Write(buffer, 0, count);
}
看来编码员使用有关底层流实现的先验知识,stream.Read 将始终返回 0 OR 请求的大小。对我来说,这似乎是一个冒险的赌注。但如果 GZipStream 的文档确实说明了这一点,那就没问题了。但是,由于 MSDN 示例使用通用 Stream
变量,因此检查读取的确切字节数更为正确。
第一个链接的示例以写入和读取方式使用 MemoryStream。位置在两者之间重置,因此将读取首先写入的数据:
Stream s = new MemoryStream();
for (int i = 0; i < 100; i++)
{
s.WriteByte((byte)i);
}
s.Position = 0;
链接的第二个示例未设置流位置。如果确实如此,您通常会看到对 Seek
的调用。您可能会将数据缓冲区的偏移量与流位置混淆?
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
偏移量实际上是缓冲区的偏移量,而不是流的偏移量。流在读取时会自动前进。
The offset is actually the offset of the buffer, not the stream. Streams are advanced automatically as they are read.