参考:msdn
在.NET Framework中,System.IO命名空间主要包含基本文件(和基于内存)的输入输出(I/O)服务的相关基础类库。
System.IO命名空间的多数类型主要用于编程操作物理目录和文件,而另一些类型则提供了从字符串缓冲区和内存区域中读写数据的方法。
System.IO 命名空间的主要成员
非抽象类:可以直接实例的(如果可以的话)
抽象类:
Directory(Info)和File(Info)类型
System.IO提供了4个类型来现实对单个文件和计算机目录结构的操作。前两个类型Directory和File通过各种静态成员现实建立、删除、复制和移动操作。与之紧密关联的FileInfo和DirectoryInfo类型则通过实际级方法来现实类似的功能(new 关键字)。由下图可以看出,Directory和File类型直接扩展了System.Object,而DirectoryInfo和FileInfo则从FileSystemInfo抽象类派生。
一般说,FileInfo和DirectoryInfo是获取文件或目录细节(如创建时间、读写能力等)更好的方式,因为它们的成员往往返回强类型的对象。相反,Directory和File类成员往往返回简单字符串而不是强类型。很多情况,你可以使用他们完成相同的工作。
FileSystemInfo抽象基类
为 FileInfo 和 DirectoryInfo 对象提供基类。
在获取文件特性前使用Refresh()方法能确保当前文件(或目录)的统计信息是最新的。
派生的类可以继承 FileSystemInfo 仅当派生的类具有从 AllAccess 权限 FileIOPermissionAccess 枚举。
在接受路径的成员,该路径可以引用的文件或只是一个目录。 指定的路径也可以指的相对路径或服务器和共享名称的通用命名约定 (UNC) 路径。 例如,以下所有条件都可接受的路径︰
-
在 C# 中,"c:\MyDir\MyFile.txt"或者"c:MyDirMyFile.txt"在 Visual Basic 中。
-
在 C# 中,"c:\MyDir"或者"c:MyDir"在 Visual Basic 中。
使用DirectoryInfo类型
我们首先套讨论的用于I/O的类型是DirectoryInfo类。它包含一组用来创建、移动、删除和枚举所有目录/子目录的成员。
除基类外的属性,方法
//绑定到当前的应用程序目录 DirectoryInfo dir1 = new DirectoryInfo("."); // @ 转义字符 DirectoryInfo dir2 = new DirectoryInfo(@"C:Windows"); //带斜杠的需要转义字符
我们传入的构造函数的路径在物理计算机上存在的。如果试图使用一个不存在的目录,系统会引发System.IO.DirectoryNotFoundException异常。如果指定了一个尚未创建的目录,线调用Create()方法,在进行操作。
//我指定一个我电脑上不存的目录 DirectoryInfo dir = new DirectoryInfo(@"E:C#MyTest");
//dir.Create();//不存的你可以创建一个 try { dir.Delete(); //进行操作就会报错 Console.WriteLine("FullName:{0}", dir.FullName); //直接进行操作 } catch (DirectoryNotFoundException me) { Console.WriteLine(me.Message); } Console.ReadLine();
我们创建一个DirectoryInfo对象,获取一下基本信息
DirectoryInfo dir = new DirectoryInfo(@"E:SQLShopping"); Console.WriteLine("*****基本信息*****"); Console.WriteLine("FullName:{0}",dir.FullName); Console.WriteLine("Name:{0}",dir.Name); Console.WriteLine("Parent:{0}",dir.Parent); Console.WriteLine("Creation:{0}",dir.CreationTime); Console.WriteLine("Attributes:{0}",dir.Attributes); Console.WriteLine("Root:{0}",dir.Root); Console.ReadLine();
使用DirectoryIno类型枚举出文件
DirectoryInfo dir = new DirectoryInfo(@"C:UsersSealiPictures小牛电动"); //获取所有*.jpg文件 第一个参数指定了搜索选项 FileInfo[] imagesFile = dir.GetFiles("*.jpg", SearchOption.AllDirectories); //返回FileInfo类型 Console.WriteLine("找到{0} *.jpg文件", imagesFile.Count()); foreach (FileInfo item in imagesFile) { Console.WriteLine("*********"); Console.WriteLine("文件名:{0}", item.Name); Console.WriteLine("文件大小:{0}", item.Length); Console.WriteLine("创建时间:{0}", item.CreationTime); Console.WriteLine("特性:{0}", item.Attributes); Console.WriteLine("*********"); } Console.ReadLine();
使用DirectoryInfo类型创建子目录
我们能使用DirectoryInfo.CreateSubdirectory()方法以编程方式扩展目录结构,使用这个方法,可以建立一个子目录,也可以一次建立多个嵌套子目录。
DirectoryInfo dir = new DirectoryInfo(@"c:"); dir.CreateSubdirectory("MyFolder"); DirectoryInfo myDir=dir.CreateSubdirectory(@"MyFolder2Data"); //返回DirectoryInfo类型
使用Directory类型
公开用于通过目录和子目录进行创建、移动和枚举的静态方法。 无法继承此类。 Directory的静态成员实现 由DirectoryInfo定义的实例级成员的大部分功能。Directory成员返回的是字符串数据而不是强类型的FileInfo和DirectoryInfo对象。
一些常用方法:
//获取驱动器 string[] drives =Directory.GetLogicalDrives(); Parallel.For(0, drives.Length - 1, i => { Console.WriteLine("-->{0}",drives[i]); }); Directory.Delete(@"C:MyFoler"); //是否删除子目录 Directory.Delete(@"C:MyFoler",true);
使用 DriveInfo类类型
提供对有关驱动器的信息的访问。
//得到所有驱动器的信息 DriveInfo[] myDrives = DriveInfo.GetDrives(); foreach (DriveInfo item in myDrives) { Console.WriteLine("Name:{0}",item.Name); Console.WriteLine("Type:{0}",item.DriveType); if (item.IsReady) { Console.WriteLine("Free space:{0}",item.TotalFreeSpace); Console.WriteLine("Format:{0}",item.DriveFormat); Console.WriteLine("Label:{0}",item.VolumeLabel); } Console.WriteLine(); } Console.ReadLine();
使用FileInfo类
提供用于创建、复制、删除、移动和打开文件的属性和实例方法,并且帮助创建 FileStream 对象
大部分FileIno类的成员返回一个I/O相关的特定对象(FileStream和StreamWrite等),然我们以不同格式从关联文件读或向关联文件写数据。
FileInfo.Create()方法
//在C盘创建一个文件 FileInfo f = new FileInfo(@"C:Test.bat"); FileStream fs = f.Create();//返回文件流对象 //使用对象 //关闭文件流 fs.Close(); //一般情况下流使用完毕后需要手动关一下
FileInfo.Create()方法返回一个FileStream对象,FileStream能对基层的文件进行同步/异步的读/写操作。FileStream对象给所有的用户授予完全读写操作权限。还需要注意一点,在使用了当前FileStream对象之后,要确保关闭句柄来释放流的底层非托管资源。由于FileStream实现了IDisposable。我们可以使用Using来释放。
using (FileStream fs = f.Create()) { }
FileInfo.Open()方法
我们能使用FileInfo.Open()方法来打开现有文件,同时也能使用它来创建文件,它比FileInfo.Create()多了很多细节,因为Open()通常有好几个参数,可以限定所操作的文件的整体结构。
//在C盘创建一个文件 FileInfo f = new FileInfo(@"C:Test2.bat"); using (FileStream fs = f.Open(FileMode.OpenOrCreate,FileAccess.ReadWrite,FileShare.None)) { }
FileInfo.OpenRead()和FileInfo.OpenWrite()方法
使用Open()需要设置才能配置我们需要的FileSteam,而这方法可以很快的返回已经设置了的FileStream.
//在C盘创建一个文件 FileInfo f = new FileInfo(@"C:Test2.bat"); //一个只读的流 using (FileStream fs =f.OpenRead()) { } //一个只写的流 using (FileStream ff=f.OpenWrite()) { }
FileInfo.OpenText()方法
它于之前的方法不同,它返回的是一个StreamReader类型而不是FileStream类型。
using (StreamReader fs =f.OpenText()) { }
StreamReader类型提供了从基层文件读取字符数据的方法
FileInfo.CreateText()和FileInfo.AppendText()方法
using (StreamWriter fs =f.AppendText()) { } using (StreamWriter ff = f.CreateText()) { }
StreamWriter类型提供向基层文件写入字符数据的方法
使用File类型
File静态成员提供了和FileInfo类型差不多的功能
using (FileStream fs =File.Create(@"C:A.txt")) { } using (FileStream ff =File.Open(@"C:A.txt",FileMode.OpenOrCreate,FileAccess.ReadWrite,FileShare.None)) { } using (FileStream f1=File.OpenRead(@"A.txt")) { } using (FileStream f1=File.OpenWrite("A.txt")) { } using (StreamReader f1 = File.OpenText("A.txt")) { } using (StreamWriter f1 = File.CreateText("A.txt")) { } using (StreamWriter f1 = File.AppendText("A.txt")) { }
其他File成员
例如:
Console.WriteLine("请开始你的表演:"); string[] maTasks={"666","777","888","5555" }; File.WriteAllLines(@"C:Test.txt",maTasks); foreach (string item in File.ReadAllLines(@"C:Test.txt")) { Console.WriteLine("TODO:{0}",item); } Console.ReadLine();
很明显,你如果希望快速获取文件句柄的话,使用File类型能节省很多的代码使用FileInfo类型的好处是能从FileSytemInfo抽象基类定义的成员中获取文件属性。
Stream抽象流
我们知道了许多获取FileStream、StreamReader和StreamWriter对象的方法,但是还没有使用这么对象从文件读取数据或者向文件写入数据。在I/O操作中,流代表了在源文件和目标文件之间传输一定量的数据。无论使用什么设备(文件、网络连接和打印机等)存储或者显示字节,“流”都能提供一种通用的方法来和字节队列进行交互。
抽象类System.IO.Stream定义了许多成员来提供对存储媒介(比如基层的文件或内存地址)实行同步或异步交互的支持。
流不仅仅局限于文件输入/输出。.NET类库提供了“流”来访问网络、内存地址和其他一些于流相关的抽象设备。
定义:
使用FileStream
继承了Stream抽象类。
一些额外的方法:
Console.WriteLine("请开始你的表演:"); //获取文件流 using (FileStream fStrem=File.Open(@"C:Test.txt",FileMode.Create)) { //把字符串编码转成字节 流做的操作都是关于字节数组的 string msg = "Hello!"; byte[] msgByteArry = Encoding.Default.GetBytes(msg); //把字节数组写入文件 fStrem.Write(msgByteArry, 0, msgByteArry.Length); //重置流内部的位子 写完之后流的位置在最后 我要读取的时候需要从第一个开始读 fStrem.Position = 0; Console.WriteLine("输入字符串的字节数组"); byte[] byteFromFile=new byte[msgByteArry.Length]; for (int i = 0; i < msgByteArry.Length; i++) { byteFromFile[i] = (byte)fStrem.ReadByte(); Console.WriteLine(byteFromFile[i]); } Console.WriteLine("解码后的字符串:"); Console.WriteLine(Encoding.Default.GetString(byteFromFile)); } Console.ReadLine();
FileStream类的缺点:需要操作原始字符串。
MemoryStream 类
创建一个流,其后备存储为内存。
使用StreamWriter和StreamReader类型
当需要读写基于字符的数据(比如字符串)的时候,StreamWriter和StreamReader类型就非常有用了。它们都默认使用Unicode字符。
我们先去看看基类的方法
注:
TextWriter 是的抽象基类 StreamWriter 和 StringWriter, ,它将字符写入到流和字符串,分别。 创建的实例 TextWriter 若要将对象写入一个字符串,请将字符串写入到一个文件,或要序列化 XML。 您还可以使用的一个实例 TextWriter 将文本写入自定义的后备存储区使用相同的 Api,则需要使用一个字符串或流,或添加对文本格式的支持。
所有 Write 方法 TextWriter 将基元数据类型作为参数将写出值作为字符串。
注;
StreamWriter 默认情况下使用的一个实例 UTF8Encoding 除非另行指定。 此实例的 UTF8Encoding 构建时没有字节顺序标记 (BOM),因此其 GetPreamble 方法返回一个空字节数组。 此构造函数的默认 utf-8 编码的无效字节上引发的异常。 此行为是由中的编码对象的行为不同 Encoding.UTF8 属性。 若要指定物料清单并确定是否对无效字节引发异常,请使用构造函数接受的编码对象将作为一个参数,如 StreamWriter(String, Boolean, Encoding) 或 StreamWriter。
写文本文件:
Console.WriteLine("请开始你的表演:"); //得到一个StreamWriter对象并写入字符串数据 这样不要把字符串转成字节数组进行写 using (StreamWriter sr = File.CreateText(@"test.txt")) { sr.WriteLineAsync("这是第一行!"); sr.WriteLineAsync("这是第二行!"); sr.WriteLineAsync("这是第三行!"); for (int i = 0; i < 10; i++) { sr.WriteAsync(i + " "); } sr.WriteAsync(sr.NewLine); } Console.WriteLine("完成"); Console.ReadLine();
读文本文件:
从TextReader类继承。
using (StreamReader sr = File.OpenText(@"test.txt")) { string input = null; while ((input = sr.ReadLine()) != null) { Console.WriteLine(input); } }
直接创建 StreamWriter/StreamReader 类型
可以是有多种方法实现相同的结果。
using (StreamWriter sw=new StreamWriter(@"tes.txt")) { } using (StreamReader sw = new StreamReader(@"tes.txt")) { }
使用StringWriter和StringReader类型
这些是可以将文本信息当做内存中的字符一样来处理。同样继承自 TextWriter和TextReader。
using (StringWriter strWriter=new StringWriter()) { strWriter.WriteLine("你哈啊"); Console.WriteLine("字符串为:{0}",strWriter); StringBuilder sb = strWriter.GetStringBuilder(); sb.Insert(0, "Hey!"); Console.WriteLine("-->{0}",sb.ToString()); sb.Remove(0,"Hey!".Length); Console.WriteLine("-->{0}",sb.ToString()); using (StringReader sr = new StringReader(strWriter.ToString())) { Console.WriteLine(sr.ReadLine()); } }
使用BinaryWriter和BinaryReader
最后研究读取器和编写器,他们都是派生System.Object。这些类型可以让我们从基层流中以简洁的二进制格式读取或写入离散数据类型。
BinaryStrem补充了BinaryWriter的功能。
FileInfo f = new FileInfo(@"test.txt"); //写入 using (BinaryWriter sw = new BinaryWriter(f.OpenWrite())) { Console.WriteLine("基础流:{0}",sw.BaseStream); double d = 123.67; string a = "A,B.C"; int ia = 34567; sw.Write(d); sw.Write(a); sw.Write(ia); } //读取 using (BinaryReader br = new BinaryReader(f.OpenRead())) { Console.WriteLine(br.ReadDouble()); Console.WriteLine(br.ReadInt32()); Console.WriteLine(br.ReadString()); }
本篇的介绍也就到这了。更多的信息自行搜索。