I/O
1.System.IO命名空间
System.IO命名空间主要包括了基于文件(和基于内存)的输入输出(I/O)服务的相关基础类库。
2.Directory(Info)和File(Info)
FileInfo和DirectoryInfo是获取文件类型或目录细节更好的方式,因为它们的成员往往会返回强类型的对象。
FileSystemInfo属性及抽象方法:
属性/抽象方法 | 作用 |
---|---|
Attribute | 获取或设置当前文件关联的特性,由FileAttributes枚举表示 |
CreateTime | 获取或设置当前文件或目录的创建时间 |
Exists | 判断指定文件或目录是否存在 |
Fullname | 获取目录或文件的完整路径 |
LastAccessTime | 获取或设置上次访问当前文件或目录的时间 |
LastWriteTime | 获取或设置上次写入当前文件或目录的时间 |
Name | 获取当前文件或目录的名称 |
Delete() | 删除指定文件或目录 |
Refresh() | 确保当前文件或目录统计信息为最新 |
3.使用DirectoryInfo类型
DirectoryInfo类型的主要成员:
成员 | 作用 |
---|---|
Create()h和CreateSubdirectory() | 按照路径名建立一个目录或一组子目录 |
Delete() | 删除一个目录和它的所有内容 |
GetDirectories() | 返回一个表示当前目录中所有子目录的DirectoryInfo对象数组 |
GetFile() | 返回FileInfo对象数组,表示指定目录下的一组文件 |
MoveTo() | 将一个目录及其内容移动到新路径 |
Parent | 获取指定目录的父目录 |
Root | 获取路径的根部分 |
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
DirectoryInfo dir1 = new DirectoryInfo("."); //当前应用程序目录 DirectoryInfo dir2 = new DirectoryInfo(@"C:\Windows"); // 使用逐字字符串 DirectoryInfo dir3 = new DirectoryInfo(@"C:\New"); dir3.Create(); //创建新目录 using System; using System.IO; class Program { static void Main(string[] args) { Console.WriteLine("***** Fun with Directory(Info) *****\n"); ShowWindowsDirectoryInfo(); ; Console.ReadLine(); } static void ShowWindowsDirectoryInfo() { // Dump directory information. DirectoryInfo dir = new DirectoryInfo(@"C:\Windows"); Console.WriteLine("***** Directory Info *****"); 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.WriteLine("**************************\n"); } }
输出结果如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
***** Fun with Directory(Info) ***** ***** Directory Info ***** FullName: C:\Windows Name: Windows Parent: Creation: 4/12/2018 5:04:33 AM Attributes: Directory Root: C:\ **************************
3.1 使用DirectoryInfo类型枚举出文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Program { static void Main(string[] args) { Console.WriteLine("***** Fun with Directory(Info) *****\n"); DisplayImageFiles(); ; Console.ReadLine(); } static void DisplayImageFiles() { DirectoryInfo dir = new DirectoryInfo(@"C:\Windows\Web\Wallpaper"); // GetFiles()方法返回FileInfo类型的数组 FileInfo[] imageFiles = dir.GetFiles("*.jpg", SearchOption.AllDirectories); Console.WriteLine("Found {0} *.jpg files\n", imageFiles.Length); foreach (FileInfo f in imageFiles) { Console.WriteLine("***************************"); Console.WriteLine("File name: {0}", f.Name); Console.WriteLine("File size: {0}", f.Length); Console.WriteLine("Creation: {0}", f.CreationTime); Console.WriteLine("Attributes: {0}", f.Attributes); Console.WriteLine("***************************\n"); } } }
3.2 使用DirectoryInfo类型创建子目录
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Program { static void Main(string[] args) { Console.WriteLine("***** Fun with Directory(Info) *****\n"); ModifyAppDirectory(); Console.ReadLine(); } static void ModifyAppDirectory() { DirectoryInfo dir = new DirectoryInfo("."); // 在初始目录下创建\MyFolder dir.CreateSubdirectory("MyFolder"); // 捕获返回的DirectoryInfo类型 DirectoryInfo myDataFolder = dir.CreateSubdirectory(@"MyFolder2\Data"); // 输出路径 Console.WriteLine("New Folder is: {0}", myDataFolder); } }
输出结果如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
***** Fun with Directory(Info) ***** New Folder is: C:\Users\kylew\Desktop\ConsoleApp1\ConsoleApp1\bin\Debug\MyFolder2\Data
4.使用Directory类型
Directory成员返回的是字符串数据而不是强类型的DirectoryInfo对象
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Program { static void Main(string[] args) { Console.WriteLine("***** Fun with Directory(Info) *****\n"); FunWithDirectoryType(); Console.ReadLine(); } static void FunWithDirectoryType() { // 列出当前所有驱动器 string[] drives = Directory.GetLogicalDrives(); Console.WriteLine("Here are your drives:"); foreach (string s in drives) Console.WriteLine("--> {0} ", s); // 删除之前建立的目录 Console.WriteLine("Press Enter to delete directories"); Console.ReadLine(); try { Directory.Delete(@"C:\MyFolder"); // 第二个参数指定是否删除子目录 Directory.Delete(@"C:\MyFolder2", true); } catch (IOException e) { Console.WriteLine(e.Message); } } }
输出结果如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
***** Fun with Directory(Info) ***** Here are your drives: --> C:\ --> D:\ --> E:\ Press Enter to delete directorie
5.使用DriveInfo类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Program { static void Main(string[] args) { Console.WriteLine("***** Fun with DriveInfo *****\n"); // 获取所有驱动器信息 DriveInfo[] myDrives = DriveInfo.GetDrives(); foreach (DriveInfo d in myDrives) { Console.WriteLine("Name: {0}", d.Name); Console.WriteLine("Type: {0}", d.DriveType); // 检查驱动器是否准备好 if (d.IsReady) { Console.WriteLine("Free space: {0}", d.TotalFreeSpace); Console.WriteLine("Format: {0}", d.DriveFormat); Console.WriteLine("Label: {0}", d.VolumeLabel); } Console.WriteLine(); } Console.ReadLine(); } }
输出结果如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
***** Fun with DriveInfo ***** Name: C:\ Type: Fixed Free space: 225707257856 Format: NTFS Label: OSDisk Name: D:\ Type: Fixed Free space: 236758802432 Format: NTFS Label: Data Name: E:\ Type: CDRom
6.使用FileInfo类
FileInfo核心成员:
成员 | 作用 |
---|---|
AppendText() | 创建一个StreamWriter类型,用来向文件追加文本 |
CopyTo() | 将现有文件复制到新文件 |
Create() | 创建一个新文件并返回一个FileStream,通过它与新文件进行交互 |
CreateText() | 创建一个写入新文本文件的StramWriter对象 |
Delete() | 删除FileInfo实例绑定的对象 |
Directory | 获取父目录的实例 |
DirectoryName | 获取父母录的完整路径 |
Length | 获取当前文件的大小 |
MoveTo() | 将指定文件移到新位置,并提供指定新文件名的选项 |
Name | 获取文件名 |
Open() | 用各种读/写访问权限和共享权限打开文件 |
OpenRead() | 创建只读FileDtream对象 |
OpenText() | 创建从现有文本文件中读取数据的StreamReader |
OpenWrite() | 创建只写FileStream类型 |
6.1 FileInfo.Create()方法
使用FileInfo.Create()方法建立文件句柄
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
static voia Main() { FileInfo f = new FileInfo(@"C:\Test.dat"); // 新建文件 FileStream fs = f.Create(); // 返回的FileStream对象给所有用户授予完全读写权限 // 使用FileStream对象 fs.Close();// 非托管资源,关闭文件流 } static void Main() { FileInfo f = new FileInfo(@"C:\Test.dat"); using (FileStream fs = f.Create()) // 为I/O类型定义using域 { // 使用FileStream对象 } }
6.2 FileInfo.Open()方法
使用FileInfo.Open()方法打开现有文件,同时也能用来创建新文件。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
static void Main() { FileInfo f2 = new FileInfo(@"C:\Test2.dat"); using (FileStream fs2 = f2.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Nonoe)) { //使用FileStream对象 } }
重载的Open()方法需要三个参数,第一个参数指定I/O请求的基本方式(比如新建文件、打开现有文件和追加文件),它的值有FileMode枚举指定:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public enum FileMode { CreateNew, // 新建文件,若存在则抛出异常 Create, // 新建文件,若存在则覆盖 Open, // 打开既有文件,若不存在则抛出异常 OpenOrCreate, // 若文件存在则打开,否则新建文件 Truncate, // 打开文件并截断文件为0字节大小 Append // 打开文件,移动到文件尾部,开始写操作,若不存在则新建文件 }
第二个参数的值由FileAccess枚举定义,用来决定基层流的读写行为:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public enum FileAccess { Read, Write, ReadWrite }
第三个参数FileShare指定文件在其他文件处理程序中的共享方式:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public enum FileShare { Delete, Inheritable, None, Read, ReadWrite, Write }
6.3 FileInfo.OpenRead()和FileInfo.OpenWrite()方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
static void Main() { // 得到一个只读的FileStream对象 FileInfo f3 = new FileInfo(@"C:\Test3.dat"); using (FileStream readOnlyStream = f3.OpenRead()) { // 使用FileStream对象 } // 得到一个只写的FileStream对象 FileInfo f4 = new FileInfo(@"C:\Test4.dat"); using (FileStream writeOnlyStream = f4.OpenRead()) { // 使用FileStream对象 } }
6.4 FileInfo.OpenText()方法
FileInfo.OpenText()方法返回的是一个StreamReader类型(而非FileStream类型)的实例。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
static void Main() { FileInfo f5 = new FileInfo(@"C:\boot.ini"); using (StreamReader sreader = f5.OpenText()) { // 使用StreamReader对象 } }
StreamReader类型提供了从基层文件读取字符数据的方法。
6.5 FileInfo.CreateText()方法和FileInfo.AppendText()方法
CreateText()方法和AppendText()方法都返回一个StreamWriter对象
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
static void Main() { FileInfo f6 = new FileInfo(@"C:\Test6.txt"); using (StreamWriter swriter = f6.CreateText()) { // 使用StreanWriter对象 } FileInfo f7 = new FileInfo(@"C:\Test6.txt"); using (StreamWriter swriterAppend = f6.AppendText()) { // 使用StreanWriter对象 } }
StreamWriter类型提供了从基层文件写入字符数据的方法。
7.使用File类
File类型的静态成员提供了与FileInfo类型差不多的功能,前面的每一个FileStream示例都可以用File类型来简化
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
static void Main() { using (FileStream fs = File.Create(@"C:\Test.dat")) {} using (FileStream fs2 = File.Open(@"C:\Test2.dat", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Nonoe)) {} using (FileStream readOnlyStream = File.OpenRead(@"C:\Test3.dat")) {} using (FileStream writeOnlyStream = File.OpenRead(@"C:\Test4.dat")) {} using (StreamReader sreader = File.OpenText(@"C:\boot.ini")) {} using (StreamWriter swriter = File.CreateText(@"C:\Test6.txt")) {} using (StreamWriter swriterAppend = File.AppendText(@"C:\Test6.txt")) {} }
File类型提供了一些独有的成员,可以极大地简化读写文本数据的过程:
方法 | 作用 |
---|---|
ReadAllBytes() | 打开指定文件,以字节数组形式返回二进制数据,然后关闭文件 |
ReadAllLines() | 打开指定文件,以字符串数组形式返回字符数据,然后关闭文件 |
ReadAllText() | 打开指定文件,以System.String形式返回字符数据,然后关闭文件 |
WriteAllBytes() | 打开指定文件,写入字节数组,然后关闭文件 |
WriteAllLines() | 打开指定文件,写入字符串数组,然后关闭文件 |
WriteAllText() | 打开指定文件,写入字符数据,然后关闭文件 |
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Program { static void Main() { Console.WriteLine("*** Simple I/O with the File type ***"); string[] myTasks = { "Fix bathroom sink", "Call Dave", "Call Mom and Dad", "Play Xbox 360" }; File.WriteAllLines(@"C:\tasks.txt", myTasks); foreach (string task in File.ReadAllLines(@"C:\tasks.txt")) { Console.WriteLine("TODO: {0}", task); } Console.ReadKey(); } }
输出结果如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
*** Simple I/O with the File type *** TODO: Fix bathroom sink TODO: Call Dave TODO: Call Mom and Dad TODO: Play Xbox 360
8.Stream抽象类
抽象Stream成员:
成员 | 作用 |
---|---|
CanRead、CanWrite、CanSeek | 检测当前流是否支持读、写的寻址 |
Close() | 关闭当前流并释放与之关联的所有资源 |
Flush() | 使用当前的缓冲状态更新基层的数据源或存储库 |
Lenght | 返回流的长度,以字节表示 |
Position | 检测在当前流中的位置 |
Read()和ReadByte() | 从当前流读取字节序列(或一个字节),并将此流中的位置偏移读取的字节数 |
Seek() | 设置当前流中的位置 |
SetLength() | 设置当前六的长度 |
Write()和WriteByte() | 向当前流中写入字节序列(或一个字节),并将此流中的当前位置偏移写入的字节数 |
使用FileStream
因为FileStream只能处理原始字节,所以必须把System.String编码成相应的字节数组,使用System.Text下的Encoding类型实现字符串与字节数组间的编码/解码。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.IO; using System.Text; namespace FileStreamApp { class Program { // Don't forget to import the System.Text and System.IO namespaces. static void Main(string[] args) { Console.WriteLine("***** Fun with FileStreams *****\n"); try { // 获取一个FileStream对象 using (FileStream fStream = File.Open(@"D:\myMessage.dat", FileMode.Create)) { // 把字符串编码成字节数组 string msg = "Hello!"; byte[] msgAsByteArray = Encoding.Default.GetBytes(msg); // 将byte[]写入文件 fStream.Write(msgAsByteArray, 0, msgAsByteArray.Length); // 重置流内部位置 fStream.Position = 0; // Read the types from file and display to console. Console.Write("Your message as an array of bytes: "); byte[] bytesFromFile = new byte[msgAsByteArray.Length]; for (int i = 0; i < msgAsByteArray.Length; i++) { bytesFromFile[i] = (byte)fStream.ReadByte(); Console.Write(bytesFromFile[i]); } // 显示解码后字符串 Console.Write("\nDecoded Message: "); Console.WriteLine(Encoding.Default.GetString(bytesFromFile)); } } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.ReadLine(); } } }
输出结果如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
***** Fun with FileStreams ***** Your message as an array of bytes: 7210110810811133 Decoded Message: Hello!
9.使用StreamWriter和StreamReader类型
StreamWriter和StreamReader类默认使用Unicode字符。StreamWriter类型从TextWriter抽象基类派生。 TextWriter核心成员:
成员 | 作用 |
---|---|
Close() | 关闭当前编写器并释放任何与之关联的系统资源 |
Flush() | 清理当前编写器的所有缓冲区,使所有缓冲数据写入基础设备,但不关闭编写器 |
NewLine | 代表派生的编写器类的行结束符字符串(\r\n) |
Write() | 此重载方法将一行写入文本流,不跟行结束符 |
WriteLine() | 此重载方法将一行写入流,后跟行结束符 |
9.1 写文本文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.IO; class Program { static void Main(string[] args) { Console.WriteLine("***** Fun with StreamWriter / StreamReader *****\n"); // Get a StreamWriter and write string data. using (StreamWriter writer = File.CreateText("reminders.txt")) { writer.WriteLine("Don't forget Mother's Day this year..."); writer.WriteLine("Don't forget Father's Day this year..."); writer.WriteLine("Don't forget these numbers:"); for (int i = 0; i < 10; i++) writer.Write(i + " "); // Insert a new line. writer.Write(writer.NewLine); } Console.WriteLine("Created file and wrote some thoughts..."); Console.ReadLine(); } }
9.2 读文本文件
TextReader主要成员:
成员 | 作用 |
---|---|
Peek() | 返回下一个可用字符,而不更改读取器位置,返回-1表示已经到了流的尾部 |
Read() | 从输出流中读取数据 |
ReadBlock() | 从当前流中读取最大计数字符,并从索引开始将数据写入缓冲区 |
ReadLine() | 从当前流中读取一行字符,并将数据作为字符串返回(返回空字符串代表EOF) |
ReadToEnd() | 读取从当前位置到流结尾的所有字符,并将它们作为一个字符串返回 |
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Program { static void Main(string[] args) { Console.WriteLine("***** Fun with StreamWriter / StreamReader *****\n"); Console.WriteLine("Here are your thoughts:\n"); using (StreamReader sr = File.OpenText("reminders.txt")) { string input = null; while ((input = sr.ReadLine()) != null) { Console.WriteLine(input); } } Console.ReadLine(); } }
输出结果入下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
***** Fun with StreamWriter / StreamReader ***** Here are your thoughts: Don't forget Mother's Day this year... Don't forget Father's Day this year... Don't forget these numbers: 0 1 2 3 4 5 6 7 8 9
9.3 直接创建StreamWriter/StreamReader类型
可以通过直接创建StreamWriter/StreamReader类型来使用StreamWriter/StreamReader。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
static void Main() { // 得到一个StreamWriter,然后写入字符串数据 using (StreamWriter writer = new StreamWriter("reminders.txt")){} // 从文件读取数据 using (StreamReader sr = new StreamReader("reminders.txt")){} }
10.使用StringWriter和StringReader类型
使用StringWriter和StringReader类型,可以将文本信息当作内存中的字符一样来处理。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.IO; using System.Text; namespace StringReaderWriterApp { class Program { static void Main(string[] args) { Console.WriteLine("***** Fun with StringWriter / StringReader *****\n"); // Create a StringWriter and emit character data to memory. using (StringWriter strWriter = new StringWriter()) { strWriter.WriteLine("Don't forget Mother's Day this year..."); Console.WriteLine("Contents of StringWriter:\n{0}", strWriter); // Get the internal StringBuilder. StringBuilder sb = strWriter.GetStringBuilder(); sb.Insert(0, "Hey!! "); Console.WriteLine("-> {0}", sb.ToString()); sb.Remove(0, "Hey!! ".Length); Console.WriteLine("-> {0}", sb.ToString()); } using (StringWriter strWriter = new StringWriter()) { strWriter.WriteLine("Don't forget Mother's Day this year..."); Console.WriteLine("Contents of StringWriter:\n{0}", strWriter); // Read data from the StringWriter. using (StringReader strReader = new StringReader(strWriter.ToString())) { string input = null; while ((input = strReader.ReadLine()) != null) { Console.WriteLine(input); } } } Console.ReadLine(); } } }
输出结果如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
***** Fun with StringWriter / StringReader ***** Contents of StringWriter: Don't forget Mother's Day this year... -> Hey!! Don't forget Mother's Day this year... -> Don't forget Mother's Day this year... Contents of StringWriter: Don't forget Mother's Day this year... Don't forget Mother's Day this year...
11.使用BinaryWriter和BinaryReader
使用BinaryWriter和BinaryReader可以从基层流中以简介的二进制格式读取或写入离散数据类型,可以读取数据,而非字符串。 BinaryWriter核心成员:
成员 | 作用 |
---|---|
BaseStream | 此只读属性提供了BinaryWriter对象使用的基层流的访问 |
Close() | 关闭二进制流 |
Flush() | 刷新二进制流 |
Seek() | 设置当前流位置 |
Write() | 将值写入当前流 |
BinaryReader核心成员:
成员 | 作用 |
---|---|
BaseStream | 此只读属性提供了BinaryWriter对象使用的基层流的访问 |
Close() | 关闭二进制阅读器 |
PeekChar() | 返回下一个可用的字符,且不改变指针位置 |
Read() | 读取给定的字节或字符,并把它们存入数组 |
ReadXXXX() | 定义了许多Read()方法来从流中获取下一个类型(ReadBoolean()、ReadByte()和ReadInt32()) |
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.IO; class Program { static void Main(string[] args) { Console.WriteLine("***** Fun with Binary Writers / Readers *****\n"); // 为文件打开一个二进制编写器 FileInfo f = new FileInfo("BinFile.dat"); using (BinaryWriter bw = new BinaryWriter(f.OpenWrite())) { // 输出BaseStream类型,此处为System.IO.FileStream Console.WriteLine("Base stream is: {0}", bw.BaseStream); double aDouble = 1234.67; int anInt = 34567; string aString = "A, B, C"; // 写入数据 bw.Write(aDouble); bw.Write(anInt); bw.Write(aString); } Console.WriteLine("Done!"); // 从流中读取二进制数据 using (BinaryReader br = new BinaryReader(f.OpenRead())) { Console.WriteLine(br.ReadDouble()); Console.WriteLine(br.ReadInt32()); Console.WriteLine(br.ReadString()); } Console.ReadLine(); } }
输出结果如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
***** Fun with Binary Writers / Readers ***** Base stream is: System.IO.FileStream Done! 1234.67 34567 A, B, C