当前位置:   article > 正文

C# 流Stream详解(1)——读写txt和二进制文件_c# stream

c# stream

【读写txt文件】

电脑手机上有各种各样的文件,例如视频文件、图片文件、文本文件,其中读写txt文件是最简单的,有多种方式,

使用StreamReader和StreamWriter

  1. //读取文件
  2. string path = @"C:\example.txt"; // 文件路径
  3. using (StreamReader reader = new StreamReader(path))//使用using语句来确保资源被正确释放,以避免资源泄漏
  4. {
  5. string line;
  6. while ((line = reader.ReadLine()) != null) // 逐行读取文件内容,每次读取一行,读取到末尾的时候为空
  7. {
  8. Console.WriteLine(line); // 输出每行内容到控制台
  9. }
  10. }
  11. //写入文件
  12. string path = @"C:\example.txt"; // 文件路径
  13. using (StreamWriter writer = new StreamWriter(path))
  14. {
  15. string content = "Hello, World!"; // 要写入文件的内容
  16. writer.WriteLine(content); // 写入一行内容到文件
  17. }

使用TextReader和TextWriter 

  1. //读取文件
  2. string path = @"C:\example.txt"; // 文件路径
  3. using (TextReader reader = new StreamReader(path))
  4. {
  5. string line;
  6. while ((line = reader.ReadLine()) != null) // 逐行读取文件内容
  7. {
  8. Console.WriteLine(line); // 输出每行内容到控制台
  9. }
  10. }
  11. //写入文件
  12. string path = @"C:\example.txt"; // 文件路径
  13. using (TextReader reader = new StreamReader(path))
  14. {
  15. string line;
  16. while ((line = reader.ReadLine()) != null) // 逐行读取文件内容
  17. {
  18. Console.WriteLine(line); // 输出每行内容到控制台
  19. }
  20. }

 使用FileStream

  1. //读取文件
  2. string path = @"C:\example.txt"; // 文件路径
  3. using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
  4. {
  5. using (StreamReader reader = new StreamReader(fs))
  6. {
  7. string line;
  8. while ((line = reader.ReadLine()) != null) // 逐行读取文件内容
  9. {
  10. Console.WriteLine(line); // 输出每行内容到控制台
  11. }
  12. }
  13. }
  14. //写入文件
  15. string path = @"C:\example.txt"; // 文件路径
  16. using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
  17. {
  18. using (StreamWriter writer = new StreamWriter(fs))
  19. {
  20. string content = "Hello, World!"; // 要写入文件的内容
  21. writer.WriteLine(content); // 写入一行内容到文件
  22. }
  23. }

使用File类提供的静态方法

上面几种方法代码都很长,一般来说我们几乎不会使用这些方法,使用File类提供的静态方法更便捷一些。如果文件非常大,还是要用上面的方法读文件,否则一次性读进来,内存会爆。

如果期望追加写入,还是要用上面的方法,StreamWriter的参数设置为true就好,例如StreamWriter sw = new StreamWriter(filePath, true);

  1. //读取文件
  2. string path = @"C:\example.txt"; // 文件路径
  3. string content = File.ReadAllText(path); // 读取整个文件内容
  4. Console.WriteLine(content); // 输出文件内容到控制台
  5. //写入文件
  6. string path = @"C:\example.txt"; // 文件路径
  7. string content = "Hello, World!"; // 要写入文件的内容
  8. File.WriteAllText(path, content); // 将内容写入文件
  9. //上面是一次性读取写入,得到的对象是一个非常大的string,但有时我们需要逐行处理,就要逐行读取写入
  10. string path = @"C:\example.txt"; // 文件路径
  11. string[] lines = File.ReadAllLines(path); // 读取所有行
  12. foreach (string line in lines)
  13. {
  14. Console.WriteLine(line); // 在控制台输出每一行
  15. }
  16. string path = @"C:\example.txt"; // 文件路径
  17. string[] lines = { "第一行内容", "第二行内容", "第三行内容" }; // 字符串数组,每个元素将成为一行
  18. File.WriteAllLines(path, lines); // 将字符串数组中的所有元素写入到文件中

文本编码

如果读出来的内容是乱码,建议了解文本编码,在读取和写入文本时都可以传递文本编码参数。

【读写二进制文件】 

使用BinaryWriter和BinaryReader

我们知道在磁盘上只会存储二进制数据,文本文件最后也会被保存为二进制文件,我们调用接口读取和写入时虽然用的是string,但到底层一定是byte[]。这就涉及到string到byte[]的编码和byte[]到string的解码,只不过对于文本文件而言,有确定的编码解码规则,我们不需要关心。

而读写二进制文件,需要你自己设置编码解码规则。编码解码的类型不止是string,可能是各种类型的。

  1. //写入文件
  2. using (BinaryWriter writer = new BinaryWriter(File.Open("file.bytes", FileMode.Create)))
  3. {
  4. bool boolValue = true;
  5. writer.Write(boolValue);
  6. int intValue = 123;
  7. writer.Write(intValue);
  8. float floatValue = 3.14f;
  9. writer.Write(floatValue);
  10. double doubleValue = 3.1415926;
  11. writer.Write(doubleValue);
  12. char charValue = 'A';
  13. writer.Write(charValue);
  14. string content = "永恒之星";
  15. byte[] bytes = Encoding.UTF8.GetBytes(content);
  16. writer.Write(bytes.Length); // 写入字符串长度
  17. writer.Write(bytes); // 写入字符串字节数组
  18. }

 读取文件时按照写入的顺序一个个读取即可。

  1. //读取文件
  2. using (BinaryReader reader = new BinaryReader(File.Open("file.bytes", FileMode.Open)))
  3. {
  4. bool boolValue = reader.ReadBoolean();
  5. Debug.Log(boolValue);
  6. int intValue = reader.ReadInt32();
  7. Debug.Log(intValue);
  8. float floatValue = reader.ReadSingle();
  9. Debug.Log(floatValue);
  10. double doubleValue = reader.ReadDouble();
  11. Debug.Log(doubleValue);
  12. char charValue = reader.ReadChar();
  13. Debug.Log(charValue);
  14. int length = reader.ReadInt32();
  15. byte[] bytes = reader.ReadBytes(length);
  16. string content = Encoding.UTF8.GetString(bytes);
  17. Debug.Log(content);
  18. }

使用MemoryStream

上面的问题在于是一次次读写的,会有多次IO开销,可以借助MemoryStream将文件内容先一次性读写到内存中,然后再读写到磁盘中。

另外,我们读写数据时是一行行代码读写的,如果有一万个数据,当然不可能写一万行代码,所以对同类型的数据需要将数据个数也写入,用for循环减少代码量。

  1. //写入文件
  2. using (MemoryStream ms = new MemoryStream())
  3. {
  4. using (BinaryWriter writer = new BinaryWriter(ms))
  5. {
  6. bool boolValue = true;
  7. writer.Write(boolValue);
  8. int count = 5;
  9. writer.Write(count);
  10. for (int i = 0; i < count; i++)
  11. {
  12. int intValue = 123;
  13. writer.Write(intValue);
  14. }
  15. float floatValue = 3.14f;
  16. writer.Write(floatValue);
  17. double doubleValue = 3.1415926;
  18. writer.Write(doubleValue);
  19. char charValue = 'A';
  20. writer.Write(charValue);
  21. string content = "永恒之星";
  22. byte[] bytes = Encoding.UTF8.GetBytes(content);
  23. writer.Write(bytes.Length); // 写入字符串长度
  24. writer.Write(bytes); // 写入字符串字节数组
  25. }
  26. File.WriteAllBytes("file.bytes", ms.ToArray());//一次性写入磁盘
  27. }
  28. //读取文件
  29. using (MemoryStream ms = new MemoryStream(File.ReadAllBytes("file.bytes")))//一次性从磁盘读取数据
  30. {
  31. using (BinaryReader reader = new BinaryReader(ms))
  32. {
  33. bool boolValue = reader.ReadBoolean();
  34. Debug.Log(boolValue);
  35. int count = reader.ReadInt32();
  36. for (int i = 0; i < count; i++)
  37. {
  38. int intValue = reader.ReadInt32();
  39. Debug.Log(intValue);
  40. }
  41. float floatValue = reader.ReadSingle();
  42. Debug.Log(floatValue);
  43. double doubleValue = reader.ReadDouble();
  44. Debug.Log(doubleValue);
  45. char charValue = reader.ReadChar();
  46. Debug.Log(charValue);
  47. int length = reader.ReadInt32();
  48. byte[] bytes = reader.ReadBytes(length);
  49. string content = Encoding.UTF8.GetString(bytes);
  50. Debug.Log(content);
  51. }
  52. }

拓展

如果我们有很多不同类型的数据需要写到不同的二进制文件中,而且后期的数据结构还可能会修改,那么每次自己读写就非常繁琐,维护成本很高。我们需要借助些序列化工具帮忙读写,我们只需要定义好数据结构,并填充数据即可。这些工具有BinaryFomatter、ProtoBuf、FlatBuffer,更具需求选择合理的工具。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/367421
推荐阅读
相关标签
  

闽ICP备14008679号