入门级学习C#语言,避免不了想让自己的程序能和外界打交道,哪怕是一个 txt 的记事本,那么怎么实现文件的操作,这里只是举个小例子,还有待开发和修正哈

如果是只是为了研究这个操作怎么写,就建立一个 C# 的命令行工程就行了,我这里是为了做上位机,整了个windows的窗体设计,随便画了个界面,显示一下我操作的结果,界面有点丑属性都没改,就像这样,只是为了看一下

【C#】_文件操作_字符串的读写 - 图1

为了方便使用我造了 FileOperation 这个类,把文件写和文件读作为类下的两个静态方法,多多少少设计的还是不太合理,但这里只是为了演示功能

文件的读取

  1. public static string ReadFile()
  2. {
  3. byte[] byData = new byte[60];
  4. char[] charData = new char[60];
  5. try
  6. {
  7. FileStream aFile = new FileStream("Data.txt",FileMode.Open);
  8. aFile.Read(byData, 0, 60);
  9. }
  10. catch (IOException e)
  11. {
  12. Func<string> ErrorMessage = new Func<string>(e.ToString);
  13. return "Read Failed: An IO eapectation has been thrown " + ErrorMessage;
  14. }
  15. Decoder d = Encoding.UTF8.GetDecoder();
  16. d.GetChars(byData, 0, byData.Length, charData, 0);
  17. return ("Read Successful: " + new string(charData));
  18. }

以上是文件操作的读方法,因为使用 FileStream 类只能处理字节,先声明好了字节数组用来接收字节流,也提前准备好等长度的字符数组,将有关文件操作的代码封装在 try 中以应对可能抛出的异常,同时也方便我们看到。这里因为我是想把它显示在我的窗体中的文本控件里所以返回了字符串,同时返回一下错误信息看一下,这里的错误信息说要委托才能转字符串,所以就简易委托一下,感觉有点随便哈,具体怎么实现比较好还得再研究一下,不是目前的重点。

通过 FileStream 类得到记事本里的数据后,只是一个字节数据,需要处理一下。为此,使用 System.Text 名称空间的 Decoder 类。此类用于将原始字节转换为更有用的项。声明一个解码器,基于UTF-8编码形式。再调用 GetChars 方法,将它转换为字符数组,这里之前声明好的字符数组就派上了用场。返回时再用 string 的初始化器,把字符数组转换成字符串。

在文件操作时其实还有一种方法,利用 StreamReader ,它可以直接读入字符串,也比较容易,但没有 FileStream 灵活,FileStream 的处理字节的功能使它除了文本还可以处理其它的数据文件,比如图像和声音。比较复杂的就是需要对字节数据进行处理,利用几种转换类来实现。

其中一些方法后面的参数就不详细说了,参考编写时的 IDE 的提示吧。

文件的写入

  1. public static string WriteFile()
  2. {
  3. byte[] byData;
  4. char[] charData;
  5. try
  6. {
  7. charData = "I typed in a string.".ToCharArray();
  8. byData = new byte[charData.Length];
  9. Encoder e = Encoding.UTF8.GetEncoder();
  10. e.GetBytes(charData, 0, charData.Length, byData, 0, true);
  11. FileStream aFile = new FileStream("Data.txt", FileMode.Create);
  12. aFile.Seek(0, SeekOrigin.Begin);
  13. aFile.Write(byData, 0, byData.Length);
  14. aFile.Close();
  15. return "Write Successful: AimFile Data.txt";
  16. }
  17. catch (IOException e)
  18. {
  19. Func<string> ErrorMessage = new Func<string>(e.ToString);
  20. return "Write Failed: An IO eapectation has been thrown " + ErrorMessage;
  21. }
  22. }

文件的写入就是上面文件的文件的读取的逆过程,事先准备好字节数组和字符数组,大小先不定,由我们想要写入的字符串的长度来决定。同样封装在 try 里,将字符串用字符数组装起来,对比着读取的解码器,这里声明一个编码器,把字符数字转成字节数组。

多出来的 Seek 的方法调用,是重定义一下文件指针的位置,从头写入。值得注意的是,这里专门调用了一下 Close 的方法,因为在调试的时候发现,如果没有用 Close 写入后如果立马读取会导致读取失败。像下图这样

【C#】_文件操作_字符串的读写 - 图2
可以看到,写入成功,但读取失败。所以我结合学过的C语言的文件操作,我觉得是因为写的时候,文件打开后写入,还没关上就读,相当于同时操作一个文件,这是不允许的,C语言有严格的文件打开和关闭的操作,那么C#应该也有,一找果然有,就是这个 Close 方法,但是在调用时 IDE 提醒我说,这个东西一般不直接用,容易出问题。这个应该和C#自身的文件操作特性有关,因为单独调用读,或调用写,都无需特别留意,打开了文件后关没关上,C#的机制会令其过一段时间就自己关上。只是这里我们研究时比较苛刻,刚写入就要读。加上 Close 的方法,就可以看到正确的结果了。
【C#】_文件操作_字符串的读写 - 图3
IDE提醒我不直接调用 Close 那么应该还有更好的处理方法,还有待研究,总而言之,可以顺利地从记事本里读数据和写数据了