没有找到合适的产品?
联系客服协助选型:023-68661681
提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
原创|其它|编辑:郝浩|2009-05-27 09:20:27.000|阅读 868 次
概述:Stream.Read 方法 当在派生类中重写时,从当前流读取字节序列,并将此流中的位置提升读取的字节数。
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
Stream.Read 方法
当在派生类中重写时,从当前流读取字节序列,并将此流中的位置提升读取的字节数。
语法:
public abstract int Read(byte[] buffer, int offset, int count)
参数:
buffer: 字节数组。此方法返回时,该缓冲区包含指定的字符数组,该数组的 offset 和 (offset + count -1) 之间的值由从当前源中读取的字节替换。
offset: buffer 中的从零开始的字节偏移量,从此处开始存储从当前流中读取的数据。
count: 要从当前流中最多读取的字节数。
返回值:
读入缓冲区中的总字节数。如果当前可用的字节数没有请求的字节数那么多,则总字节数可能小于请求的字节数,或者如果已到达流的末尾,则为零 (0)。
备注:
此方法的实现从当前流中读取最多的 count 个字节,并将它们存储在从 offset 开始的 buffer 中。流中的当前位置提升已读取的字节数;但是,如果出现异常,流中的当前位置保持不变。实现返回已读取的字节数。仅当位置当前位于流的末尾时,返回值才为零。如果没有任何可用的数据,该实现将一直阻塞到至少有一个字节的数据可读为止。仅当流中不再有其他的数据,而且也不再需要更多的数据(如已关闭的套接字或文件尾)时,Read 才返回 0。即使尚未到达流的末尾,实现仍可以随意返回少于所请求的字节。
请注意上述的 MSDN 中的最后一句话。我们写一个程序来验证这一点:
using System;
using System.IO;
using Skyiv.Util;
namespace Skyiv.Ben.StreamTest
{
sealed class Program
{
static void Main()
{
var bs = new byte[128 * 1024];
var stream = new FtpClient("ftp://ftp.hp.com", "anonymous", "ben@skyiv.com").
GetDownloadStream("pub/softpaq/allfiles.txt"); // 568,320 bytes
var br = new BinaryReader(stream);
Display("Expect", bs.Length);
Display("Stream.Read", stream.Read(bs, 0, bs.Length));
Display("BinaryReader.Read", br.Read(bs, 0, bs.Length));
Display("BinaryReader.ReadBytes", br.ReadBytes(bs.Length).Length);
Display("Stream.Readbytes", stream.ReadBytes(bs.Length).Length);
}
static void Display(string msg, int n)
{
Console.WriteLine("{0,22}: {1,7:N0}", msg, n);
}
}
}
将这个程序运行三次的结果如下:
Expect: 131,072
Stream.Read: 50,604
BinaryReader.Read: 11,616
BinaryReader.ReadBytes: 131,072
Stream.Readbytes: 131,072
Expect: 131,072
Stream.Read: 1,452
BinaryReader.Read: 2,904
BinaryReader.ReadBytes: 131,072
Stream.Readbytes: 131,072
Expect: 131,072
Stream.Read: 4,356
BinaryReader.Read: 131,072
BinaryReader.ReadBytes: 131,072
Stream.Readbytes: 131,072
可见,Stream.Read 方法和 BinaryReader.Read 方法在尚未到达流的末尾情况下可以返回少于所请求的字节。
通过使用 Reflector 来查看 BinaryReader.Read 方法的源程序代码,如下:
public virtual int Read(byte[] buffer, int index, int count)
{
if (buffer == null)
{
throw new ArgumentNullException
("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
}
if (index < 0)
{
throw new ArgumentOutOfRangeException
("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (count < 0)
{
throw new ArgumentOutOfRangeException
("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if ((buffer.Length - index) < count)
{
throw new ArgumentException
(Environment.GetResourceString("Argument_InvalidOffLen"));
}
if (this.m_stream == null)
{
__Error.FileNotOpen();
}
return this.m_stream.Read(buffer, index, count);
}
上述代码最后一行中 m_stream 的类型为 Stream,就是 BinaryReader 类的基础流。可见,BinaryReader.Read 方法在做一些必要的检查后就是简单地调用 Stream.Read 方法。
而 BinaryReader.ReadBytes 方法的源程序代码如下:
public virtual byte[] ReadBytes(int count)
{
if (count < 0)
{
throw new ArgumentOutOfRangeException
("count", Environment.GetResourceString
("ArgumentOutOfRange_NeedNonNegNum"));
}
if (this.m_stream == null)
{
__Error.FileNotOpen();
}
byte[] buffer = new byte[count];
int offset = 0;
do
{
int num2 = this.m_stream.Read(buffer, offset, count);
if (num2 == 0)
{
break;
}
offset += num2;
count -= num2;
}
while (count > 0);
if (offset != buffer.Length)
{
byte[] dst = new byte[offset];
Buffer.InternalBlockCopy(buffer, 0, dst, 0, offset);
buffer = dst;
}
return buffer;
}
从上述代码中可以看出,BinaryReader.ReadBytes 方法循环地调用 Stream.Read 方法,直到达到流的末尾,或者已经读取了 count 个字节。也就是说,如果没有到达流的末尾,该方法就一定会返回所请求的字节。
MSDN 文档中对这两个方法的描述:
BinaryReader.Read 方法:将 index 作为字节数组中的起始点,从流中读取 count 个字节。
BinaryReader.ReadBytes 方法:从当前流中将 count 个字节读入字节数组,并使当前位置提升 count 个字节。
上述两个方法的备注: BinaryReader 在读取失败后不还原文件位置。
也就是说,虽然 BinaryReader.Read 方法和 Stream.Read 方法一样在尚未到达流的末尾情况下可以返回少于所请求的字节,但是在 MSDN 文档中并没有指出这一点,我们写程序的时候要小心,避免掉入这个陷阱。
上述的测试程序中用到了 Stream.ReadBytes 方法,其实是一个扩展方法,源程序代码如下:
using System;
using System.IO;
namespace Skyiv.Util
{
static class ExtensionMethods
{
public static byte[] ReadBytes(this Stream stream, int count)
{
if (count < 0) throw new ArgumentOutOfRangeException("count", "要求非负数");
var bs = new byte[count];
var offset = 0;
for (int n = -1; n != 0 && count > 0; count -= n, offset += n)
n = stream.Read(bs, offset, count);
if (offset != bs.Length) Array.Resize(ref bs, offset);
return bs;
}
}
}
上述的测试程序中还使用了 FtpClient 类,可以参见我的另一篇随笔“如何直接处理FTP服务器上的压缩文件”,其源程序代码如下:
using System;
using System.IO;
using System.Net;
namespace Skyiv.Util
{
sealed class FtpClient
{
Uri uri;
string userName;
string password;
public FtpClient(string uri, string userName, string password)
{
this.uri = new Uri(uri);
this.userName = userName;
this.password = password;
}
public Stream GetDownloadStream(string sourceFile)
{
Uri downloadUri = new Uri(uri, sourceFile);
if (downloadUri.Scheme != Uri.UriSchemeFtp)
throw new ArgumentException("URI is not an FTP site");
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(downloadUri);
ftpRequest.Credentials = new NetworkCredential(userName, password);
ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
return ((FtpWebResponse)ftpRequest.GetResponse()).GetResponseStream();
}
}
}
我在上一篇随笔“【算法】利用有限自动机进行字符串匹配”中给出了一道思考题如下:
上面的第二个 C# 程序中有一个 bug,但是这个 bug 在绝大多数情况下都不会表现出来。所以这个程序能够 Accepted。
亲爱的读者,你能够找出这个 bug 吗?
提示,这个 bug 和字符串匹配算法无关,并且第一个 C# 程序中不存在这个 bug 。
上述思考题中的第二个 C# 程序的 Main 方法如下所示:
static void Main()
{
var s = new byte[10000000 + 2 * 1000 + 100];
int i = 0, n = Console.OpenStandardInput().Read(s, 0, s.Length);
while (s[i++] != '\n') ;
for (int c, q = 0; i < n; q = 0)
{
while ((c = s[i++]) != '\n')
if (q < 99 && c != '\r') q = delta[q, Array.IndexOf(a, c) + 1];
Console.WriteLine((q < 4) ? "YES" : "NO");
}
}
这个 bug 至今还没有人找到。实际上,该方法的头两个语句应改为:
var s = new BinaryReader
(Console.OpenStandardInput()).ReadBytes(10000000 + 2 * 1000 + 100);
int i = 0, n = s.Length;
这是因为 Steam.Read 方法在尚未到达流的末尾情况下可以返回少于所请求的字节,这有可能导致只读取了部分输入而产生 bug 。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com
文章转载自:自互联网接DevExpress原厂商通知,将于近日上调旗下产品授权价格,现在下单客户可享受优惠报价!
面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@evget.com
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢
慧都科技 版权所有 Copyright 2003-
2025 渝ICP备12000582号-13 渝公网安备
50010702500608号