文件系统数据
文件作用:文件是在应用程序的实例之间存储数据的一种遍历方式, 也可以用于在应用程序之间传输数据. 文件可以存储用户和应用程序配置,以便下次运行应用程序时检索它们.
基本概念:
流(stream)
在.NET Framework中进行的所有输入输出工作都要用到流(stream). 流是序列化设备(serial device)的抽象表示. 序列化设备可以线性方式存储数据, 并可按同样方式访问: 一次访问一个字节. 此设备可以是磁盘文件、网络通道、内存位置或其他支持以线性方式读写的对象. 把设备编程抽象的, 就可以隐藏流的底层目标和源. 这种抽象的级别支持代码重用, 允许编写更通用的例程, 因为不用担心数据传输方式的特性.因此当应用程序从文件输入流、网络输入流或者其他流中读取数据时, 就可以传输和重用类似的代码. 而且, 使用文件流还可以忽略每种设备的物理机制, 不必担心硬盘头或内存分配问题.
两种类型的流:
输出流: 当向某些外部目标写入数据时, 就要用到输出流. 这可以是物理磁盘文件、网络位置、打印机或另一个程序. 理解流编程技术可以带来很多高级应用
输入流: 用于将数据读入程序可以访问的内存或变量中. 到目前为止, 我们使用的最常见的输入流形式是键盘. 输入流可以来自任何源.
System.IO名称空间
System.IO包含用于在文件中读写数据的类, P622 图21-1
表21-1 用于访问文件系统的类
类 | 说明 |
File | 静态实用类, 提供许多静态方法, 用于移动、复制和删除文件 |
Directory | 静态实用类, 提供许多静态方法, 用于移动、复制和删除目录 |
Path | 实用类, 用于处理路径名称 |
FileInfo | 表示磁盘上的物理文件, 该类包含处理此文件的方法. 要完成对文件的读写工作, 就必须创建Stream对象 |
DirectoryInfo | 磁盘上的物理目录, 该类包含处理此目录的方法. |
FileSystemInfo | 用作FileInfo和DirectoryInfo的基类, 可以使用多态性同时处理文件和目录 |
FileStream | 表示可写或可读, 或二者均可的文件. 可以同步或异步地读写此文件. |
StreamReader | 从流中读取字符数据, 可以使用FileStream作为基类创建. |
StreamWriter | 向流中写入字符数据, 可以使用FileSystem作为基类创建. |
FileSystemWatcher | 用于监视文件和目录, 提供了这些文件和目录发生变化时应用程序可以捕获的事件. |
FileStream对象
FIleStream对象表示指向磁盘或网咯路径上的文件的流. 这个类提供了在文件中读写字节的方法, 但经常使用StreamReader或StreamWriter执行这些功能. 这是因为FileStream类操作的是字节和字节数组,而Stream类操作的是字符数据. 字符数据易于使用, 但是有些操作, 如随机文件访问, 就必须由FileStream对象执行.
主要关注构造函数:
两个参数:
FileStreamaFile = new FileStream(filename, FileMode.<Member>);
三个参数:
FileStreamaFile = new FIleStream(filename, FileMode.<Member>,FileAccess.<Member>);
P627
FileMode和FileAccess都是枚举类型
FileMode用于指示使用哪种方式打开文件, 对于每种模式, 文件存在与否都有不同的操作
成员 | 文件存在 | 文件不存在 |
Append | 打开文件, 流指向文件的末尾处, 只能与枚举FileAccess.Write结合使用. | 创建一个新文件. 只能与枚举FileAccess.Write结合使用. |
Create | 删除该文件, 然后创建新文件 | 创建新文件 |
CreateNew | 抛出异常 | 创建新文件 |
Open | 打开文件, 流指向文件开头处 | 抛出异常 |
OpenOrCreate | 打开文件, 流指向文件开头处 | 创建新文件 |
Truncate | 打开文件, 清除其内容. 流指向文件开头处, 保留文件的初始创建日期. | 抛出异常 |
FIleAccess 是文件访问权限, Read Write ReadWrite
使用FileStream类读取数据不像StreamReader类读取数据那样容易. 这是因为FileStream类智能处理原始字节(rawbyte). 处理原始字节的功能使FileStream类可以用于任何数据文件, 而不仅仅是文本文件. 通过读取字节数据,FileStream对象可以用于读取诸如图像和声音的文件. 这种灵活性的代价是, 不能使用FileStream类将数据直接读入字符串.
字节数组 byte[] byteData = new byte[200];
字符数组 char[] charData = new char[200];
使用FileStream.Read()方法是从FileStream对象所指向的文件中访问数据的主要手段
using System;
usingSystem.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
usingSystem.Threading.Tasks;
namespace Ch21Ex1
{
class Program
{
static void Main(string[] args)
{
byte[] byteData = new byte[200];
char[] charData = new char[200];
try
{
FileStream aFile = newFileStream("../../Program.cs", FileMode.Open);
aFile.Seek(144,SeekOrigin.Begin);
aFile.Read(byteData, 0, 200);
}
catch (IOException e)
{
Console.WriteLine("An IOexception has been thrown!");
Console.WriteLine(e.ToString());
Console.ReadKey();
return;
}
Decoder d =Encoding.UTF8.GetDecoder();
d.GetChars(byteData,0,byteData.Length, charData, 0);
Console.WriteLine(charData);
Console.ReadKey();
}
}
}
aFile.Seek(144, SeekOrigin.Begin);------从文件开头处向后移动指针144个字节, 指针指在145个字节处.
aFile.Read(byteData,0, 200);------将指针移动0个字节, 读取后面200个字节的数据到byteData中.
使用try…catch(IOException e)
在文件I/O涉及的所有操作几乎都可以抛出IOException类型的异常. 所有产品代码都必需包含错误处理, 在处理文件系统时尤其如此.
读取了字节数组, 还是无法显示出可读的内容, 需要将其转换成字符数组用于显示. 为此, 需要使用System.Text名称空间的Decoder类. 此类用于将原始字节转换成更有用的项,比如字符:
Decoder d= Encoding.UTF8.GetDecoder();
d.GetChars(byteData,0, byteData.Length, charData, 0);
先创建一个用于UTF8编码的解码器d
然后使用
d.GetChars(byteData,0, byteData.Length, charData, 0);
转换成charData
好处是可以使用Seek随意指定指针的位置, 也就是可以随机读取数据.
坏处是读取过程繁琐,
写入数据
首先创建一个字节数组; 构建要写入文件的字符数组; 然后使用Encoder对象将其转换为字节数组, 最后调用Write()方法
using System;
usingSystem.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
usingSystem.Threading.Tasks;
namespace写入数据
{
class Program
{
static void Main(string[] args)
{
byte[] byteData;
char[] charData;
try
{
FileStream aFile = newFileStream("Temp.txt", FileMode.Create);
charData = "My pink halfof the drainpipe.".ToCharArray();
byteData= new byte[charData.Length];
Encoder e =Encoding.UTF8.GetEncoder();
e.GetBytes(charData, 0,charData.Length, byteData, 0, true);
//将指针指向开头
aFile.Seek(0,SeekOrigin.Begin);
aFile.Write(byteData, 0,byteData.Length);
}
catch (IOException e)
{
Console.WriteLine("An IOexception has been thrown");
Console.WriteLine(e.ToString());
Console.ReadKey();
return;
}
}
}
}
① 先声明两个数组: 一个字符数组, 一个字节数组.
② 给字节数组赋值, 使用字符串的ToCharArray()方法. 将字符串转换成字符数组.
先声明byteData数组, 如果需要在之后的代码中声明数组大小,就要注意声明方法.
③ 使用FileStream类建一个文本文件
④ 再声明一个使用UTF8标准的编码器, 使用e.GetBytes()方法得到字节数组.
⑤ 使用Seek()定位指针到文件头, 使用Write()方法将字节数组写入文件中
---------------------- ASP.Net+Unity开发、 .Net培训、期待与您交流! ----------------------详细请查看: www.itheima.com