Thursday, March 6, 2008

Avoid using FileMode.OpenOrCreate to open stream

Keywords: C#, Stream, FileMode.OpenOrCreate


C#提供多种方式来创建一个具有不同读写权限的流, 这主要是通过设置不同的FileMode和FileAccess值来实现的. 我们如果要取得一个具有读写权限的流, 最好是用FileMode.Create和FileAcess.ReadWrite来获取. 源码后说明原因.



private void Test()
{
//get the main part of docx. The main part is just document.xml in docx package
PackagePart wordMainPackagePart=GetMainPart();

//load document.xml into wholeDocument object
XmlDocument wholeDocument = new XmlDocument();
using (Stream stream = wordMainPackagePart.GetStream())
{
wholeDocument.Load(stream);
}


//change the wholeDocument
//...

//save wholeDocument into document.xml. It is better avoid using FileMode.OpenOrCreate, we had better use FileMode.Create
using (Stream stream = wordMainPackagePart.GetStream(FileMode.Create, FileAccess.ReadWrite))
{
wholeDocument.Save(stream);
}
}


FileMode有几个枚举值:


FileMode.Append的意义是, 如果文件存在, 流定位到文件尾部, 新写的东西将追加到原文件尾; 如果文件不存在, 则新增文件. 这个FileMode只能和FileAccess.Write一起使用, 不能和其他的FileAccess同时使用.


FileMode.Create的意义是:如果文件存在, 首先删除文件的内容, 然后重写文件; 如果文件不存在, 则新增文件


FileMode.CreateNew的意义是: 如果文件存在, 则抛出一个异常; 如果文件不存在, 则新增文件


FileMode.Open的意义是,如果文件存在,再根据FileAccess的取值, 来确定可不可写; 如果文件不存在, 则抛出一个异常


FileMode.OpenOrCreate的意义是, 如果文件存在, 则重写这个文件, 重写的机制是不删除原有文件的内容, 那么从原文件头开始重写, 比如原有文件共10个字节, 新的内容只有5个字节的话, 则重写后的文件后5个字节仍是原有文件的内容.

FileMode.Truncate的意义是, 如果文件存在的话, 首先删除 文件的内容, 然后重写文件.


为什么我们推荐使用FileMode.Create呢, 因为FileMode.Create其实同时具有FileMode.CreateNew和FileMode.Truncate的效果, 即当文件存在的时候,它使用FileMode.Truncate方式重写文件, 当文件不存在的时候, 它使用FileMode.CreateNew来新增文件.






No comments: