分享
 
 
 

CSDN第一期总结之四:Stream的问题

王朝other·作者佚名  2007-09-14
窄屏简体版  字體: |||超大  

IO操作基本上需要用到Stream相关的子类,因此这类问题在CSDN问得也是比较多。其实对于Stream来说,操作起来比较简单,只要对细节的处理稍微注意一下,相信在使用它的时候也会得心应手。

对于Stream相关的问题,大致分如下几类。

问题一,基本操作的问题;

问题二,编码的问题;

问题三,尾部处理问题;

问题四,Stream缓存问题;

问题五,资源释放问题;

最后一个问题,说说如何使用Stream来更新大文件部分数据。

对于问题一,基本操作的问题,主要是读写问题,主要是出现在文件数据比较大,需要循环写或者读的时候。此时正确读的形式如下。

// Open a file to read

using( FileStream fs = new FileStream( yourFile,

FileMode.Open, FileAccess.Read,

FileShare.None ) )

{

int nRealRead = 0;

byte[] bBuffer = new byte[1024];

do

{

// Read data

nRealRead = fs.Read( bBuffer, 0, 1024 );

// Output data

Debug.WriteLine( Encoding.Default.GetString( bBuffer, 0, nRealRead ) );

}while( nRealRead == 1024 );

}

可是大多数人第一次完成这样操作的时候,都会在“nRealRead = fs.Read( bBuffer, 0, 1024 );”这一句犯错误。认为第二个参数的偏移量对于Stream而设的,所以认为应该用累加的值,也就是目前总共读了多少的字节数。这里需要理解一下Stream的操作,当进行读或者写操作的时候,Stream的游标会根据所读或者所写得字节而自动向前跟进;其次Stream.Read或者Stream.Write这两个方法中第二个参数是针对第一个Buffer参数而言的,而不是对于Stream的,因此不要在这个地方犯错误。

基本问题还牵扯的就是文件打开的方式。有人经常问,如何同时用两个Stream打开同一个文件。其实默认的Stream打开方式是独享的,因此当不指明文件为访问共享的时候,后打开文件操作就会出现异常,因此需要向我上面所写的那样。还有,如果需要指定当前Stream的起始位置,可以通过Seek方法或者设置Position属性来完成。

对于问题二,编码问题。有人使用Stream的子类,例如StreamReader之类来打开一个文本文件,发现读出来的数据是乱码,造成这个原因大多数由于文件中含有中文字符,同时打开文件的时候没有指明编码方式。由于英文和中文的编码方式不同,因此在不指明编码的时候有时会造成读取中文错误。此时只要使用StreamReader类型中含有Encoding参数的构造函数即可,例如:

using( StreamReader sr = new StreamReader( yourFile, Encoding.Default ) )

这里只是采用系统默认的编码方式,但有可能不太适合你文件的编码方式,因此需要在实际应用去调试和变换这个参数。

问题三是,Stream尾部处理问题。此类问题所展现的现象如,复制文件的时候文件会增大。因此在使用Stream.Read和Stream.Write的时候,要通过方法的返回值,来标明真正读和写的字节数,就像前面所写的那样。

// Read data

nRealRead = fs.Read( bBuffer, 0, 1024 );

// Output data

Debug.WriteLine( Encoding.Default.GetString( bBuffer, 0, nRealRead ) );

此时在输出的时候用的不是“1024”,而是“nRealRead”做为字节有效标示。

对于问题四,Stream缓存的问题,这主要表现在写的时候。为了避免频繁操作IO而降低效率,大多数Stream采用异步写的方式,也就是Stream对象要配备有一定的缓存,来暂时保存写的数据。但缓存是有限的,当缓存已满后会造成后续写的数据不能写入,从而导致数据丢失。那么此时需要显示的调用Stream.Flush方法,来把缓存的数据写入到文件中并清空缓存。其实这并不是唯一方法,在一些Stream的子类中还提供了设置BufferSize的方法,或者提供了设置AutoFlush属性来实现自动写入等等,因此这里大家可以根据不同需要而选择不同方法来完成。

对于Stream的释放问题,这可能不单单是使用Stream的问题,可能是使用C#编程而造成的不良习惯。虽说C#的资源是受托管的,但是对于Stream来说,如果不及时释放,那么当其他线程或者进程使用此文件的时候就会造成无法打开的现象(由于Stream大多数都是以独享方式打开),而且没有及时关闭,所占用的Buffer无法及时释放。对于资源释放问题,我为此专门写过一篇文章,如果有兴趣的话不妨看看。

http://blog.csdn.net/Knight94/archive/2006/08/05/1023352.aspx

因此养成一个好的习惯至关重要。其实释放Stream很简单,要么显示的调用其的Close和Dispose这两个方法,要么使用using程序块,就像我前面所写的那样。

最后一个就是如何使用Stream来更新大文件。比较常见的就是,当文件比较大,但是需要修改的部分很少,因此想要通过Stream直接在某个位置进行类似于删除、插入或者替换等操作。

对于一个文件的更新操作,大致分为三种,这里主要是考虑更新的位置和更新数据长度。

第一种对于文件尾扩展的操作,内容长度不限;

第二种等字节的替换操作,位置不限;

最后一种就是位置不固定,字节数不确定。

上面所说的前两种,进行处理比较简单。对于第一种,只要设置FileMode的时候增加Append标示即可。而对于等字节的替换,就更简单了,直接通过Stream.Seek找到指定的位置,然后调用Stream.Write即可。

而最后一个,是最麻烦的。比较简单的解决方式,创建一个临时文件,然后一边读一边写,遇到需要修改的,先读出来再修改最后再写入。等全部写完了,删除旧文件,修改临时文件的名称为原来名字。

比较麻烦的解决方式,就是通过Share方式,用一个读Stream和一个写Stream直接操纵源文件。这里需要注意的是,为了保证新写的数据不要冲掉还没读出来的数据,也就是说要控制写Stream所写的位置不要超过要读的位置。举例说,目前需要读的位置是文件的800字节处,也就是说800字节以后还没读出来处理,此时写Stream在写完数据后,Stream的位置不能超过800字节,如果写采用的是缓存,那么超过800位置的数据不要立刻通过Flush进行提交。总的来说,通过两个Stream来操作同一个文件,对于这一点要特别注意,处理不好要造成死循环。

Stream的问题相对比较简单,大多数人操作的时候不注意细节。所以我这里只是稍加说明,不做特别细的说明。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有