文件 IO 与序列化
翻译整理自 File IO 与 Serialization。
1. File 静态类
using System.IO;
string text = File.ReadAllText("a.txt");
string[] lines = File.ReadAllLines("a.txt");
byte[] bytes = File.ReadAllBytes("b.bin");
File.WriteAllText("out.txt", "hello");
File.WriteAllLines("out.txt", new[] { "a", "b" });
File.WriteAllBytes("out.bin", new byte[] { 1, 2 });
File.AppendAllText("log.txt", "new\n");
File.Exists("a.txt");
File.Delete("a.txt");
File.Copy("a", "b");
File.Move("a", "b");2. 文件流 FileStream
using var fs = new FileStream("data.bin", FileMode.Create, FileAccess.Write);
fs.WriteByte(1);
fs.Write(new byte[] { 2, 3, 4 });using var fs = new FileStream("data.bin", FileMode.Open);
int b;
while ((b = fs.ReadByte()) != -1) Console.Write(b);3. StreamReader / Writer
using var sr = new StreamReader("a.txt");
string line;
while ((line = sr.ReadLine()) != null)
Console.WriteLine(line);
using var sw = new StreamWriter("out.txt");
sw.WriteLine("hello");
sw.Write("world");异步读写
using var sr = new StreamReader("a.txt");
string all = await sr.ReadToEndAsync();
await using var sw = new StreamWriter("out.txt");
await sw.WriteLineAsync("hello");4. Directory
Directory.CreateDirectory("a/b/c");
string[] files = Directory.GetFiles("a");
string[] dirs = Directory.GetDirectories("a");
Directory.Delete("a", recursive: true);
Directory.Exists("a");
Directory.Move("a", "b");
var all = Directory.EnumerateFiles("a", "*.cs", SearchOption.AllDirectories);5. Path
string dir = Path.GetDirectoryName("a/b.txt"); // a
string fn = Path.GetFileName("a/b.txt"); // b.txt
string ext = Path.GetExtension("a.txt"); // .txt
string n = Path.GetFileNameWithoutExtension("a.txt"); // a
string p = Path.Combine("a", "b", "c.txt"); // a/b/c.txt
string tmp = Path.GetTempFileName();
string tmpDir = Path.GetTempPath();6. JSON 序列化
System.Text.Json(.NET Core 3.0+ 起内置):
using System.Text.Json;
var u = new User { Name = "Alice", Age = 30 };
// 序列化
string json = JsonSerializer.Serialize(u, new JsonSerializerOptions
{
WriteIndented = true,
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
});
// 反序列化
User obj = JsonSerializer.Deserialize<User>(json);
// 异步
await using var fs = File.Create("u.json");
await JsonSerializer.SerializeAsync(fs, u);选项:
var opt = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
};中文/特殊字符需要
UnsafeRelaxedJsonEscaping否则会被\uXXXX转义。
7. JSON 字符串/Stream API
using var doc = JsonDocument.Parse(json);
JsonElement root = doc.RootElement;
foreach (var p in root.EnumerateObject())
Console.WriteLine($"{p.Name}: {p.Value}");
var writer = new Utf8JsonWriter(File.OpenWrite("o.json"));
writer.WriteStartObject();
writer.WriteString("name", "x");
writer.WriteEndObject();8. Xml
using System.Xml.Serialization;
var ser = new XmlSerializer(typeof(User));
using var fs = File.OpenRead("u.xml");
var u = (User)ser.Deserialize(fs);
using var w = File.Create("o.xml");
ser.Serialize(w, u);9. CSV / 自定义
简单 CSV:
var lines = File.ReadAllLines("data.csv");
foreach (var line in lines)
{
var cols = line.Split(',');
Console.WriteLine(string.Join(" | ", cols));
}10. 内存映射文件
using var mmf = MemoryMappedFile.CreateFromFile("big.bin");
using var acc = mmf.CreateViewAccessor();
for (long i = 0; i < 1L << 30; i++)
acc.ReadByte(i);11. Zip
using System.IO.Compression;
ZipFile.CreateFromDirectory("a", "a.zip");
ZipFile.ExtractToDirectory("a.zip", "out");
using var za = ZipFile.OpenRead("a.zip");
foreach (var e in za.Entries) { ... }小结
掌握 File / Stream / Json 后,IO 编程已不再是难点。Async + using 让资源管理异常安全。