文件读写
学习了一点点希望对以后的学习工作有帮助
在应用程序中基本任务是对数据的操作,这就是对数据进行访问和保存挤兑数据的读写,应用程序访问一个文本文件叫做“读”;对文本文件的内容进行修改后保存这些修改的操作被称为“写”。
C#中对流的处理
BinaryReader和BinaryWriter类,
是以二进制格式操作数据
a) Close() 关闭当前阅读器及基础流
b) Read() 从基础流中读取字符并前移流的当前位置
c) ReadDecimal() 从当前流中读取十进制数值,并将该流的当前位置前移16个字节
d) ReadByte() 从当前流中读取下一个字节,并将在流中的位置向前移动1个字节
Stream类
Stream类是IO名称空间中最重要的类之一,它派生FileStream、MemoryStream和BufferedStream等不同类型的抽象类
1、 Dispose() 释放由Stream占用的资源
2、 Read() 读取各种类型的的数据
3、 Write() 写入各种类型的数据
4、 Read 和 Write 方法读写各种不同格式的数据。 对于支持查找的流,使用 Seek 和 SetLength 方法以及 Position 和 Length 属性可查询和修改流的当前位置和长度。
5、 有些流实现执行基础数据的本地缓冲以提高性能。对于这样的流, Flush 方法可用于清除所有内部缓冲区并确保将所有数据写入基础数据源或储存库。
注意:
在实现 Stream 的派生类时,必须提供 Read 和 Write 方法的实现。 异步方法 BeginRead、 EndRead、 BeginWrite 和 EndWrite 通过同步方法 Read 和 Write 实现。 同样, Read 和 Write 的实现也将与异步方法一起正常工作。 ReadByte 和 WriteByte 的默认实现创建一个新的单元素字节数组,然后调用 Read 和 Write 的实现。 当从 Stream 派生时,如果有内部字节缓冲区,则强烈建议重写这些方法以访问内部缓冲区,这样性能将得到显著提高。 还必须提供 CanRead、 CanSeek、 CanWrite、 Flush、 Length、 Position、 Seek 和 SetLength 的实现。
不要重写 Close 方法,而应将所有 Stream 清理逻辑放入 Dispose 方法中。 有关更多信息,请参见 实现 Dispose 方法。
File类
提供创建、复制、删除、移动和打开文件的静态方法,并协助创建FileStream类。File是一静态类。直接调用其方法
自定义各种File方法的行为枚举
1、 FileAccess指定文件的读取和写入访问
2、 FileShare为已在使用的文件指定访问级别
3、 FileMode指定是保留还是覆盖现有的文件内容并指定创建现有文件的请求是否会导致异常。
a) Create创建一个新文件
b) Open指定打开现有文件
c) CreateNew新建一个文件
d) Append打开现有文件追加
File类中提供操作文件的各种方法
1、 Exists(string path) 检查文件是否存在
2、 Copy(string sourceFileName,string destFileName) 文件复制
3、 Move(string sourceFileName,string destFileName ) 文件移动
4、 Delete(string) 文件删除
class Test { public static void Main() { string path = @"c: empMyTest.txt"; if (!File.Exists(path)) { // 使用File创建文件并写入 using (StreamWriter sw = File.CreateText(path)) { sw.WriteLine("Hello"); sw.WriteLine("And"); sw.WriteLine("Welcome"); } } // 打开文件并读入 using (StreamReader sr = File.OpenText(path)) { string s = ""; while ((s = sr.ReadLine()) != null) { Console.WriteLine(s); } } } } |
FileInfo 类与File类的区别
System.IO包含另一个类File,它的功能与FileInfo一样,不过不同的是,File类成员为静态。所以,使用File代替FileInfo就不必实例化一个新FileInfo对象。
那么为什么有时还使用FileInfo呢?因为每次通过File类调用某个方法时,都要占用一定的cpu处理时间来进行安全检查,即使使用不同的File类的方法重复访问同一个文件时也是如此。而,FileInfo类只在创建FileInfo对象时执行一次安全检查。
FileStream类
公开以文件为主的Stream,
1、 FileMode为enum类型,其值如下:
Append:打开一个文件并查找到文件末尾,以便能够附加新的数据,如果文件不存在,则新建一个文件
Create:用指定名称新建一个文件,如果存在具有相同名称的文件,则覆盖旧文件
CreateNew:新建一个文件
Open:打开一个文件,指定文件必须存在
OpenOrCreate:与Open类似,只是指定文件不存在时,新建一个
Truncate:根据此枚举,打开指定文件并将之截断为0字节(大小为0字节),文件必须存在
2、 FileAccess枚举值:Read / Write / ReadWrite
3、 FileShare枚举值:
None:谢绝共享当前文件。文件关闭前,打开该文件的任何请求都将失败
Read:只能对文件进行读取操作
Write:可以对文件进行写入操作
ReadWrite:可以进行对文件的读写和写入两种操作
static void Main(string[] args) { Console.WriteLine("输入文件的名称:"); string filename = Console.ReadLine(); FileStream fileStr = new FileStream(filename, FileMode.OpenOrCreate); BinaryWriter binWrt = new BinaryWriter(fileStr); for (int i = 0; i < 20; i++) { binWrt.Write(i); } binWrt.Close(); fileStr.Close(); fileStr = new FileStream(filename, FileMode.Open, FileAccess.Read); BinaryReader binRead = new BinaryReader(fileStr); for (int i = 0; i < 20; i++) { Console.WriteLine(binRead.ReadInt32()); } binRead.Close(); fileStr.Close(); Console.ReadKey(); } |
下面演示打开一个文件:
class FSOpenWrite { public static void Main() { FileStream fs=new FileStream("c:\Variables.txt", FileMode.Append, FileAccess.Write, FileShare.Write); fs.Close(); StreamWriter sw=new StreamWriter("c:\Variables.txt", true, Encoding.ASCII); string NextLine="This is the appended line."; sw.Write(NextLine); sw.Close(); } } |
MemoryStream类
Read() 读MemoryStream并装值写入缓冲区
ReadByte() 从MemoryStream读一个字节
Write() 从缓冲区向MemoryStream写值
WriteByte() 从缓冲区向MemoryStream写一个字节
WriteTo() 将此内存流的内容写入别一个内存流
static void Main(string[] args) { MemoryStream memStr = new MemoryStream(); BufferedStream buffStr = new BufferedStream(memStr); buffStr.WriteByte((byte)100); buffStr.Position = 0; //取得memStr的当前位置Positon属性为0,以便buffStr的当前位置设置为流的开始 byte[] arrb = { 1, 2, 3 }; buffStr.Read(arrb, 0, 1); // 用流的当前位置的值填充字节数组arrb for (int i = 0; i < 3; i++) { Console.WriteLine("这个值是{0}", arrb[i]); } Console.WriteLine("ReadByte()的返回值是{0}", buffStr.ReadByte()); // 返回-1表示流的末尾 Console.ReadKey(); } |
TextStream类
TextReader 为 StreamReader 和 StringReader 的抽象基类,它们分别从流和字符串读取字符。 使用这些派生类可打开一个文本文件以读取指定范围的字符,或基于现有的流创建一个读取器。
TextReader类是StreamReader和StringReader类的抽象基类,可用于读取有序的字符序列
1、 Read() 读取输入流中的下一个字符或下一组字符
2、 ReadLine() 从当前流中读取一行字符并将数据作为字符串返回
3、 ReadToEnd() 从流的当前位置到末尾读取流
class Program { static string ans = "y"; static void Main(string[] args) { Console.WriteLine("1.读取文件"); Console.WriteLine("2.读取字符串"); try { Reading(); } catch (Exception ex) { Console.WriteLine(ex.Message); Console.ReadKey(); } } static void Reading() { if (ans == "Y" || ans == "y") { Console.Write("输入你的选择[1/2]:"); int choice = Convert.ToInt32(Console.ReadLine()); if (choice == 1) { Console.WriteLine("输入文件名:"); string filename = Console.ReadLine(); if (!File.Exists(filename)) { Console.WriteLine(filename + "不存在!"); return; } StreamReader sr = File.OpenText(filename); string input; while ((input = sr.ReadLine()) != null) { Console.WriteLine(input); } Console.WriteLine("已达到流末尾。"); sr.Close(); Console.Write("要继续吗?[Y/N]:"); ans = Console.ReadLine(); Reading(); } else if (choice == 2) { Console.Write("输入字符串:"); string str = Console.ReadLine(); char[] b = new char[str.Length]; StringReader sr = new StringReader(str); sr.Read(b, 0, str.Length); Console.WriteLine(b); Console.WriteLine("要继续吗[Y/N]:"); ans = Console.ReadLine(); Reading(); } else { Console.WriteLine("输入1或2作为选择:"); } } } } |
TextWriter类
TextWriter 是 StreamWriter 和 StringWriter 的抽象基类,它们将字符分别写入流和字符串。 创建一个 TextWriter 实例,将对象写入字符串,或将字符串写入文件,或序列化 XML。 也可使用 TextWriter 的实例将文本写入自定义后备存储区(所使用的 API 与用于字符串或流的 API 相同),或者增加对文本格式化的支持。
TextWriter 的所有使用基元数据类型作为参数的 Write 方法都将值作为字符串写出。。
想文件中写入字符串
class Program { static string ans = "y"; static void Main(string[] args) { Writing(); } static void Writing() { if (ans == "Y" || ans == "y") { Console.WriteLine("输入文件名:"); string filename = Console.ReadLine(); if (!File.Exists(filename)) { Console.WriteLine(filename + "不存在!"); return; } StreamWriter sr = File.AppendText(filename); Console.Write("输入要写入的字符串:"); string str = Console.ReadLine(); sr.WriteLine(str); sr.Close(); Console.Write("要继续吗?[Y/N]:"); ans = Console.ReadLine(); Writing(); } } } |
实现了IDisposible接口的都可以使用using包装
运用StreamReader与StreamWriter保存文件
/// <summary> /// 读取文件并显示到TextBox中 /// </summary> /// <param name="fileName">文件全路径</param> /// <param name="textBox">TextBox</param> public void StreamReaderFile(string fileName,TextBox textBox) { try { using (StreamReader reader = new StreamReader(fileName, Encoding.Default)) { textBox.Text = reader.ReadToEnd(); } } catch (Exception ex) { MessageBox.Show("读取文件失败"); } } /// <summary> /// 保存文件 /// </summary> /// <param name="fileName">文件路径</param> /// <param name="textBox">TextBox</param> public void saveFile(string fileName,TextBox textBox) { try { using (StreamWriter write = new StreamWriter(fileName, false, Encoding.Default)) { write.WriteLine(textBox.Text); MessageBox.Show("Ok"); } } catch (Exception ex) { MessageBox.Show(ex.Message); }
} |
Path类
DirectoryInfo类
取得硬盘上的文件及文件下的文件
private void Form1_Load(object sender, EventArgs e) { this.treeView1.Nodes.Clear(); TreeNode treeNode2=this.treeView1.Nodes.Add("D:"); treeNode2.Tag=@"D:"; TreeNode treeNode = treeView1.Nodes[0]; DirectoryInfo dicrectory = new DirectoryInfo(@"D:"); CreateFileInfo(treeNode,dicrectory); } public void CreateFileInfo(TreeNode treeNode,DirectoryInfo dicrectory) { DirectoryInfo[] dicrectorys = dicrectory.GetDirectories(); FileInfo[] fs = dicrectory.GetFiles(); //得到文件 foreach (DirectoryInfo di in dicrectorys) { TreeNode treeNode1 = treeNode.Nodes.Add(di.Name); treeNode1.Tag = di.FullName; treeNode1.Name = di.Name; CreateFileInfo(treeNode1,di);//运用递归 } foreach (FileInfo f in fs) { treeNode.Nodes.Add(f.Name); } } |
Directory 类
将 Directory 类用于典型操作,如复制、移动、重命名、创建和删除目录。 也可将 Directory 类用于获取和设置与目录的创建、访问及写入操作相关的 DateTime 信息。
由于所有的 Directory 方法都是静态的,所以如果只想执行一个操作,那么使用 Directory 方法的效率比使用相应的 DirectoryInfo 实例方法可能更高。 大多数 Directory 方法要求当前操作的目录的路径。
Directory 类的静态方法对所有方法都执行安全检查。 如果打算多次重用某个对象,可考虑改用 DirectoryInfo 的相应实例方法,因为并不总是需要安全检查。
静态类与非静态类的区别
静态类 |
非静态 |
用static修饰 |
不用static修饰 |
只包含静态成员 |
可以包含静态成员 |
不可以包含实例成员 |
可以包含实例成员 |
使用类名调用静态成员 |
使用实例对象调用非静态成员 |
不能被实例化 |
可以被实例化 |
不能包含实例构造函数 |
包含实例构造函数 |