! k' R/ M+ X8 e9 A. q问题二,编码的问题; 7 P/ \. R5 N7 t) m( J0 M 3 A, ?/ R& ?0 d# {9 M2 h" k问题三,尾部处理问题;' q/ T/ @& L6 i" y. O
7 I/ }" T) S. ~+ T. Z
问题四,Stream缓存问题; : Y$ t0 T2 h$ ?: f9 L& y1 C! m8 Z2 {6 v( t
问题五,资源释放问题; ' x/ d/ g: B3 p3 A$ m & f, ^* P; h- o) c最后一个问题,说说如何使用Stream来更新大文件部分数据。 % Q( l6 c" o K. L7 w' h1 Y; Z( s 9 b2 w/ X" w/ M2 N' Q对于问题一,基本操作的问题,主要是读写问题,主要是出现在文件数据比较大,需要循环写或者读的时候。此时正确读的形式如下。 " u# m& f, t* n; U0 G6 h0 e3 l8 J& q0 L5 W6 d. w& b! U% L" d# f
// Open a file to read . S+ p+ P! R- h; q' i8 c# M* I. U2 N( D0 @% u/ Z, F
using( FileStream fs = new FileStream( yourFile, ) z. Y& t3 d. A5 A9 Z+ d5 }7 c / p5 [1 O3 s% e& V; u FileMode.Open, FileAccess.Read, + s- e, }. O' O" a. x* N& U7 n6 g* ~
FileShare.None ) ) + o, P2 l X" {8 F2 e {) ^, B7 G , E; [( o" R. G; ~) | {8 t9 y& t2 `' u% b4 h. a u0 e1 s
9 A o' [$ c& V. W int nRealRead = 0; % i9 \, M# p5 y4 j K, r4 t; c D% \9 z8 f, A, x
byte[] bBuffer = new byte[1024]; , @$ i/ j) v: x* z/ W9 X 9 n* w' I% T c8 n4 P6 B do8 k* g; X# ^1 a( f
3 V8 f$ q6 [. g# M4 x
{) U F% U- d* I! L( T# ^: L
+ k2 n: |& ]. x& i // Read data - Q! K. J& ? p% a. E 4 v$ S& A9 u% t) | nRealRead = fs.Read( bBuffer, 0, 1024 ); [: g( c, k8 m, o9 F) C
3 N+ R- g4 m H( T6 v+ c p // Output data4 M& t( c+ N" Q0 y5 B
& F' v0 Z) ?: Y- M( P
Debug.WriteLine( Encoding.Default.GetString( bBuffer, 0, nRealRead ) );" U: m, K% }3 p: k
$ p2 S0 L/ P c5 ?+ n2 _/ L, i
}while( nRealRead == 1024 );" E" Y; \1 o9 I9 m6 q* K
! R4 Y6 x0 y. c) d. n5 N6 K
} ' M; A! s: D* C6 `4 y, w9 |- c, w6 H4 W5 T
可是大多数人第一次完成这样操作的时候,都会在“nRealRead = fs.Read( bBuffer, 0, 1024 );”这一句犯错误。认为第二个参数的偏移量对于Stream而设的,所以认为应该用累加的值,也就是目前总共读了多少的字节数。这里需要理解一下Stream的操作,当进行读或者写操作的时候,Stream的游标会根据所读或者所写得字节而自动向前跟进;其次Stream.Read或者Stream.Write这两个方法中第二个参数是针对第一个Buffer参数而言的,而不是对于Stream的,因此不要在这个地方犯错误。 / C3 M# G: s2 x& }! T4 i2 s' i/ c5 @6 N- U8 o1 P, H. A+ i
基本问题还牵扯的就是文件打开的方式。有人经常问,如何同时用两个Stream打开同一个文件。其实默认的Stream打开方式是独享的,因此当不指明文件为访问共享的时候,后打开文件操作就会出现异常,因此需要向我上面所写的那样。还有,如果需要指定当前Stream的起始位置,可以通过Seek方法或者设置Position属性来完成。& m7 l( w% K! V3 Z5 ?
% ?/ m$ R! v: p# t9 T! m对于问题二,编码问题。有人使用Stream的子类,例如StreamReader之类来打开一个文本文件,发现读出来的数据是乱码,造成这个原因大多数由于文件中含有中文字符,同时打开文件的时候没有指明编码方式。由于英文和中文的编码方式不同,因此在不指明编码的时候有时会造成读取中文错误。此时只要使用StreamReader类型中含有Encoding参数的构造函数即可,例如: \1 ^- l+ `, n1 y" P+ a6 c& W, v
a' C$ Z' t7 f- ?1 |
using( StreamReader sr = new StreamReader( yourFile, Encoding.Default ) )9 x6 d( A' k; C5 n/ F M. d
1 l3 w! I1 v7 S* l2 a9 O3 K( j
这里只是采用系统默认的编码方式,但有可能不太适合你文件的编码方式,因此需要在实际应用去调试和变换这个参数。8 D4 k0 T9 }/ j/ X8 |
/ s1 Y, H+ A7 w: |' ?% C
问题三是,Stream尾部处理问题。此类问题所展现的现象如,复制文件的时候文件会增大。因此在使用Stream.Read和Stream.Write的时候,要通过方法的返回值,来标明真正读和写的字节数,就像前面所写的那样。 * Z t {+ t" X7 G# [! ^' `2 |: w/ I' }. q* u
// Read data ' ~' j* ?- a4 f! s3 Y# @4 V# m # g3 O! t7 ]7 d9 Y1 S% R) d2 w nRealRead = fs.Read( bBuffer, 0, 1024 ); 9 Y( A" ], S: h: ` * T; [2 T6 ~1 n8 ?% G; X6 A // Output data& i' Q+ Z8 u4 A7 S* }
3 [; f4 p& x! \3 X9 g3 d2 a
Debug.WriteLine( Encoding.Default.GetString( bBuffer, 0, nRealRead ) );/ W p1 t- Y! Y( J5 k/ y |
2 M5 x7 w& b, q* @, y! a4 j
此时在输出的时候用的不是“1024”,而是“nRealRead”做为字节有效标示。 & g7 w3 V) w# a$ D# G - M3 V1 q! g7 a2 ], c$ t9 p对于问题四,Stream缓存的问题,这主要表现在写的时候。为了避免频繁操作IO而降低效率,大多数Stream采用异步写的方式,也就是Stream对象要配备有一定的缓存,来暂时保存写的数据。但缓存是有限的,当缓存已满后会造成后续写的数据不能写入,从而导致数据丢失。那么此时需要显示的调用Stream.Flush方法,来把缓存的数据写入到文件中并清空缓存。其实这并不是唯一方法,在一些Stream的子类中还提供了设置BufferSize的方法,或者提供了设置AutoFlush属性来实现自动写入等等,因此这里大家可以根据不同需要而选择不同方法来完成。! q" c: P6 x/ p& K% d; y
0 t, f% B1 i! I( J: P- _; s& r
对于Stream的释放问题,这可能不单单是使用Stream的问题,可能是使用C#编程而造成的不良习惯。虽说C#的资源是受托管的,但是对于Stream来说,如果不及时释放,那么当其他线程或者进程使用此文件的时候就会造成无法打开的现象(由于Stream大多数都是以独享方式打开),而且没有及时关闭,所占用的Buffer无法及时释放。对于资源释放问题,我为此专门写过一篇文章,如果有兴趣的话不妨看看。3 V( F/ ~: f) z3 N5 r
; C+ X5 m: B ?$ o3 F* v: E6 Yhttp://blog.csdn.net/Knight94/archive/2006/08/05/1023352.aspx) h! T; O$ h4 l; G8 @' x' y! M
( Y5 Z/ A: X6 H1 d
因此养成一个好的习惯至关重要。其实释放Stream很简单,要么显示的调用其的Close和Dispose这两个方法,要么使用using程序块,就像我前面所写的那样。 # I7 `) z/ [$ d# l1 c) C# M. _$ u/ N* U5 \0 i& O
最后一个就是如何使用Stream来更新大文件。比较常见的就是,当文件比较大,但是需要修改的部分很少,因此想要通过Stream直接在某个位置进行类似于删除、插入或者替换等操作。 D% U: B1 x8 T7 p
/ m9 V/ @ h) P2 G
对于一个文件的更新操作,大致分为三种,这里主要是考虑更新的位置和更新数据长度。- n% Y3 J X! ?$ u4 ]; c" n