文件系统数据(二)——FileStream//20131104

来源:互联网 发布:iapp源码 编辑:程序博客网 时间:2024/05/29 15:05

七、FileStream对象
    FileStream对象表示在磁盘或网络路径上指向文件的流。这个类提供了在文件中读写字节的方法,但经常使用StreamReader类或StreamWriter执行这些功能。这是因为FileStream类操作的是字节和字节数组,而Stream类操作的是字符数据。
FileStream aFile=new FileStream(filename,FileMode.Member,FileAccess.Member);
1、FileMode枚举包含几个成员,指定了如何打开或创建文件。成员:
(1)Append:文件存在:打开文件,流指向文件的末尾,只能与枚举FileAccess.Write联合使用;文件不存在:创建一个新文件。只能与枚举FileAccess.Write联合使用
(2)Create:文件存在:删除该文件,然后创建新文件;文件不存在:创建新文件
(3)CreateNew:文件存在:抛出异常;文件不存在:创建新文件
(4)Open:文件存在:打开现有的文件,流指向文件的开头;文件不存在:抛出异常
(5)OpenOrCreate:文件存在:打开文件,流指向文件的开头;文件不存在:创建新文件
(6)Truncate:文件存在:打开现有文件,清除其内容。流指向文件的开头,保留文件的初始创建日期;文件不存在:抛出异常

2、第三个参数是FileAccess枚举的一个成员,它指定了流的作用。成员:
(1)Read:打开文件,用于只读
(2)Write:打开文件,用于只写
(3)ReadWrite:打开文件,用于读写
注:(1)在FileStream构造函数不使用FileAccess枚举参数的版本中,使用默认值FileAccess.ReadWrite。
    (2)对文件进行非FileAccess枚举成员指定的操作会导致抛出异常。此属性的作用是,基于用户的身份验证级别改变用户对文件的访问权限。

3、FileStream类的常用方法有
(1)Close  关闭流并释放相关资源
(2)Flush  清空缓冲区,使缓冲数据被写入设备
(3)Lock  允许读取访问的同时防止其他进程修改FileStream
(4)UnLock  允许其他进程访问以前锁定的某个FileStream
(5)Read  从流中读取字节块并写入指定缓冲区
(6)ReadByte  从流中读取一个字节
(7)Write  向流中写入从指定缓冲区读取的字节块(三个参数:要写入的数组,开始写入的数组下标和要写入的字节数)
(8)WriteByte  向流中写入一个字节
(9)Seek  设置该流的读写指针位置

4、File和FileInfo类都提供了OpenRead()和OpenWrite()方法,更易于创建FileStream对象。这些都提供了快捷方式,因此不必以FileStream构造函数的参数形式提供前面所有的信息。如:
FileStream aFile=File.OpenRead("Data.txt");
下面的代码执行同样的功能:
FileInfo aFileInfo=new FileInfo("Data.txt");
FileStream aFile=aFileInfo.OpenRead();

5、文件位置
   FileStream类维护内部文件指针,该指针指向文件中进行下一次读写操作的位置。在大多数情况下,当打开文件时,它就指向文件的开始位置,但是此指针可以修改。实现此功能的方法是Seek()方法,它有两个参数:第一个参数规定文件指针以字节为单位的移动距离。第二个参数规定开始计算的起始位置,用SeekOrigin枚举的一个值表示。SeekOrigin枚举包含3个值:Begin、Current和End。
   例如:正面的代码行将文件指针移动到文件的第8个字节,其起始位置就是文件的第1个字节:
   aFile.Seek(8,SeekOrigin.Begin);
   注意读写文件时,文件指针也会改变。在读取了10个字节之后,文件指针就指向被读取的第10个字节之后的字节。
   也可以规定负查找位置,这可以与SeekOrigin.End枚举值一起使用,查找靠近文件末端的保护位置。正面的代码会查找文件中倒数第5个字节:
   aFile.Seek(-5,SeekOrigin.End);
   以这种方式访问的文件有时称为随机访问文件,因为应用程序可以访问文件中的任何位置。

6、读取数据
   使用FileStream类只能处理原始字节,处理原始字节的功能使FileStream类可以用于任何数据文件,如文本文件,图像和声音的文件。这种灵活性的代价是,不能使用FileStream类将数据直接读入字符串,而使用StreamReader类却可以这样处理。
   FileStream.Read()方法是从FileStream对象所指向的文件中访问数据的主要手段。这个方法从文件中读取数据,再把数据写入一个字节数组。它有三个参数:第一个参数是传入的字节数组,用以接受FileStream对象中的数据。第二个参数是字节数组中开始写入数据的位置。它通常是0,表示从数组开端向文件中写入数据。最后一个参数指定从文件中读出多少字节。
   从文件中获取了字节数组后,就需要将其转换为字符数组,以便在控制台显示它。为此,使用System.Text名称空间的Decoder类。如:
Decoder d=Encoding.UTF8.GetDecoder();
d.GetChars(byData,0,byData.Length,charData,0);
   这些代码基于UTF8编码模式创建了Decoder对象。这就是Unicode编码模式。然后调用GetChars()方法,此方法提取字节数组,将它转换为字符数组。

7、写入数据
   向随机访问文件中写入数据的过程与从中读取数据非常类似。首先需要创建一个字节数组;最简单的办法是首先构建要写入文件的字符数组。然后使用Encoder对象将其转换为字节数组,其用法非常类似于Decoder。最后调用Write()方法,将字节数组传送到文件中。例:
            byte[] byData;
            char[] charData;
            try
            {
              
                FileStream aFile = new FileStream("Temp.txt", FileMode.Create);
                //使用String类的ToCharArray()静态方法,创建了字符数组。因为C#中的所有事物都是对象,
                //文本“HAHA”实际上是一个String对象,所以甚至可以在字符串上调用这些静态方法。
                charData = "HAHA".ToCharArray();
                byData = new byte[charData.Length];
                Encoder e = Encoding.UTF8.GetEncoder();
                //GetBytes()方法可以将字符数组转换为字节数组,并将字符数组作为第一个参数(charData),将该数组中
                //起始位置的下标作为第二个参数(0表示数组的开头)。第三个参数是要转换的字符数量(charData数组中的元素个数)。
                //第四个参数是在其中转入数据的字节数组(byData),第五个参数是在字节数组中开始写入位置的下标(0表示byData数组的开头)。
                //最后一个参数决定在结束后Encoder对象是否应该更新其状态,即Encoder对象是否仍然保留它原来在字节数组中的内存位置。
                //最后对Encoder的调用必须将此参数设置为true,以清空其内存,释放对象,用于垃圾回收
                e.GetBytes(charData, 0, charData.Length, byData, 0, true);
                //将字符数组转换为FileStream对象需要的正确字节数组。
                aFile.Seek(0, SeekOrigin.Begin);
                //使用Write()方法向FileStream写入字节数组。
                aFile.Write(byData, 0, byData.Length);
            }
            catch (IOException ex)
            {
                Console.WriteLine("An IO exception has been thrown!");
                Console.WriteLine(ex.ToString());
                Console.ReadKey();
                return;
            }

原创粉丝点击