在 c# 编程中,文件读写是一项非常基础且重要的操作。无论是保存用户数据、读取配置文件还是处理日志信息,都离不开文件操作。本文将详细介绍 c# 中各种常用的文件读写方式,包括文本文件、二进制文件、csv 文件、json 文件等,并提供相应的代码示例,帮助你根据实际需求选择合适的方法。
一、文本文件读写
文本文件是最常见的文件类型,c# 提供了多种方式来读写文本文件。
1. 使用 file 类的静态方法
file 类提供了一系列静态方法,可以方便地进行文本文件的读写操作,适合处理小型文本文件。
using system; using system.io; class program { static void main() { // 写入文本文件 string content = "hello, world!"; string path = "test.txt"; // 写入所有文本 file.writealltext(path, content); console.writeline("文件写入成功"); // 读取所有文本 string readcontent = file.readalltext(path); console.writeline("读取的内容:" + readcontent); // 写入多行文本 string[] lines = { "第一行", "第二行", "第三行" }; file.writealllines(path, lines); console.writeline("多行文本写入成功"); // 读取所有行 string[] readlines = file.readalllines(path); console.writeline("读取的多行内容:"); foreach (string line in readlines) { console.writeline(line); } } }
优点:代码简洁,一行代码即可完成读写操作。
缺点:会将整个文件内容加载到内存中,不适合处理大型文件。
2. 使用 streamreader 和 streamwriter
streamreader 和 streamwriter 适合处理大型文本文件,可以逐行读写,节省内存。
using system; using system.io; class program { static void main() { string path = "largefile.txt"; // 使用streamwriter写入 using (streamwriter sw = new streamwriter(path)) { sw.writeline("第一行内容"); sw.writeline("第二行内容"); sw.write("这是第三行的"); sw.write("一部分内容"); } // 使用streamreader读取 using (streamreader sr = new streamreader(path)) { string line; console.writeline("文件内容:"); while ((line = sr.readline()) != null) { console.writeline(line); } } // 读取全部内容 using (streamreader sr = new streamreader(path)) { string allcontent = sr.readtoend(); console.writeline("n全部内容:"); console.writeline(allcontent); } } }
优点:可以逐行处理,内存占用小,适合大型文件。
缺点:代码相对复杂一些。
注意:使用using
语句可以确保流正确关闭和释放资源。
二、二进制文件读写
二进制文件适用于存储图像、音频、视频等非文本数据,或者需要紧凑存储的结构化数据。
1. 使用 filestream 类
filestream 是一个通用的字节流类,可以用于读写任何类型的文件。
using system; using system.io; class program { static void main() { string path = "data.bin"; // 写入二进制数据 byte[] data = { 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64 }; // "hello world"的ascii码 using (filestream fs = new filestream(path, filemode.create)) { fs.write(data, 0, data.length); } // 读取二进制数据 using (filestream fs = new filestream(path, filemode.open)) { byte[] readdata = new byte[fs.length]; fs.read(readdata, 0, readdata.length); console.writeline("读取的二进制数据转换为字符串:"); console.writeline(system.text.encoding.ascii.getstring(readdata)); console.writeline("十六进制表示:"); foreach (byte b in readdata) { console.write($"{b:x2} "); } } } }
2. 使用 binaryreader 和 binarywriter
binaryreader 和 binarywriter 提供了更方便的方法来读写基本数据类型。
using system; using system.io; class program { static void main() { string path = "binarydata.bin"; // 写入各种数据类型 using (binarywriter bw = new binarywriter(file.open(path, filemode.create))) { bw.write(123); // int bw.write(3.14159); // double bw.write(true); // bool bw.write("hello world"); // string bw.write(new char[] { 'a', 'b', 'c' }); // char数组 } // 读取各种数据类型 using (binaryreader br = new binaryreader(file.open(path, filemode.open))) { console.writeline("int值: " + br.readint32()); console.writeline("double值: " + br.readdouble()); console.writeline("bool值: " + br.readboolean()); console.writeline("string值: " + br.readstring()); char[] chars = br.readchars(3); console.writeline("char数组: " + new string(chars)); } } }
注意:使用 binaryreader 和 binarywriter 时,读取顺序必须与写入顺序一致。
三、使用 filestream 进行高级操作
filestream 提供了更多控制选项,适合需要精细控制文件操作的场景。
using system; using system.io; class program { static void main() { string sourcepath = "source.txt"; string destpath = "destination.txt"; // 创建源文件 file.writealltext(sourcepath, "这是一个用于演示文件流操作的示例文本。"); // 使用filestream复制文件 using (filestream sourcestream = new filestream(sourcepath, filemode.open, fileaccess.read)) using (filestream deststream = new filestream(destpath, filemode.create, fileaccess.write)) { byte[] buffer = new byte[1024]; int bytesread; console.writeline("开始复制文件..."); // 每次读取1024字节并写入 while ((bytesread = sourcestream.read(buffer, 0, buffer.length)) > 0) { deststream.write(buffer, 0, bytesread); console.writeline($"已复制 {bytesread} 字节"); } console.writeline("文件复制完成"); } // 验证复制结果 if (file.readalltext(sourcepath) == file.readalltext(destpath)) { console.writeline("复制的文件内容与源文件一致"); } } }
filemode 枚举:控制打开或创建文件的方式,常见值有 create、open、append 等。
fileaccess 枚举:指定对文件的访问权限,有 read、write、readwrite。
缓冲操作:使用缓冲区可以提高大文件操作的效率。
四、特定格式文件读写
1. csv 文件读写
csv(逗号分隔值)文件是一种常见的表格数据格式。
using system; using system.collections.generic; using system.io; class program { static void main() { string path = "data.csv"; // 写入csv文件 var data = new list<string[]> { new[] { "姓名", "年龄", "城市" }, new[] { "张三", "25", "北京" }, new[] { "李四", "30", "上海" }, new[] { "王五", "35", "广州" } }; using (streamwriter sw = new streamwriter(path)) { foreach (var row in data) { sw.writeline(string.join(",", row)); } } // 读取csv文件 using (streamreader sr = new streamreader(path)) { string line; while ((line = sr.readline()) != null) { string[] columns = line.split(','); console.writeline(string.join(" | ", columns)); } } } }
注意:以上是简单实现,实际应用中可能需要处理包含逗号的字段(通常用引号括起来),这时可以考虑使用专门的 csv 库如 csvhelper。
2. json 文件读写
json 是一种轻量级的数据交换格式,在现代应用中广泛使用。
需要先安装 newtonsoft.json 包(nuget 命令:install-package newtonsoft.json)
using system; using system.collections.generic; using newtonsoft.json; // 定义一个示例类 public class person { public string name { get; set; } public int age { get; set; } public string city { get; set; } } class program { static void main() { string path = "people.json"; // 创建示例数据 var people = new list<person> { new person { name = "张三", age = 25, city = "北京" }, new person { name = "李四", age = 30, city = "上海" }, new person { name = "王五", age = 35, city = "广州" } }; // 写入json文件 string json = jsonconvert.serializeobject(people, formatting.indented); file.writealltext(path, json); // 读取json文件 string jsonfromfile = file.readalltext(path); list<person> peoplefromfile = jsonconvert.deserializeobject<list<person>>(jsonfromfile); // 显示读取结果 foreach (var person in peoplefromfile) { console.writeline($"姓名: {person.name}, 年龄: {person.age}, 城市: {person.city}"); } } }
在.net core 3.0 及以上版本,也可以使用内置的 system.text.json:
// 写入json文件 string json = system.text.json.jsonserializer.serialize(people, new system.text.json.jsonserializeroptions { writeindented = true }); file.writealltext(path, json); // 读取json文件 string jsonfromfile = file.readalltext(path); list<person> peoplefromfile = system.text.json.jsonserializer.deserialize<list<person>>(jsonfromfile);
五、文件操作的注意事项
1. 异常处理
文件操作可能会抛出各种异常,如文件不存在、权限不足等,需要进行适当的异常处理。
try { string content = file.readalltext("test.txt"); console.writeline(content); } catch (filenotfoundexception) { console.writeline("文件不存在"); } catch (unauthorizedaccessexception) { console.writeline("没有访问权限"); } catch (ioexception ex) { console.writeline($"io错误: {ex.message}"); } catch (exception ex) { console.writeline($"发生错误: {ex.message}"); }
2. 路径处理
使用 path 类来处理文件路径,避免跨平台问题。
// 组合路径 string directory = "data"; string filename = "info.txt"; string fullpath = path.combine(directory, filename); console.writeline("完整路径: " + fullpath); // 获取文件名 console.writeline("文件名: " + path.getfilename(fullpath)); // 获取文件扩展名 console.writeline("扩展名: " + path.getextension(fullpath)); // 获取目录名 console.writeline("目录名: " + path.getdirectoryname(fullpath));
3. 异步操作
对于 ui 应用程序,使用异步文件操作可以避免界面卡顿。
using system; using system.io; using system.threading.tasks; class program { static async task main() { string path = "async_test.txt"; // 异步写入 string content = "这是一个异步写入的示例"; await file.writealltextasync(path, content); console.writeline("异步写入完成"); // 异步读取 string readcontent = await file.readalltextasync(path); console.writeline("异步读取内容: " + readcontent); // 异步流操作 using (streamwriter sw = new streamwriter(path, append: true)) { await sw.writelineasync("这是追加的一行"); } using (streamreader sr = new streamreader(path)) { string line; console.writeline("文件内容:"); while ((line = await sr.readlineasync()) != null) { console.writeline(line); } } } }
六、总结
c# 提供了丰富的文件操作方式,选择合适的方法取决于具体需求:
- 对于小型文本文件,file 类的静态方法最简单方便
- 对于大型文本文件,streamreader 和 streamwriter 更合适
- 对于二进制文件,使用 filestream、binaryreader 和 binarywriter
- 对于 csv 和 json 等特定格式,可使用相应的方法或库
无论使用哪种方式,都应该注意:
- 使用 using 语句确保资源正确释放
- 进行适当的异常处理
- 注意路径处理和跨平台兼容性
- 对于 ui 应用,优先考虑异步操作
掌握这些文件操作技巧,将有助于你更好地处理各种数据存储和读取需求,提高应用程序的灵活性和可靠性。
到此这篇关于c#读写文本文件的多种方式详解的文章就介绍到这了,更多相关c#读写文件内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论