学习目标

通过本章学习,你将掌握: - 文件和目录操作的基本方法 - 流(Stream)的概念和使用 - 文本文件的读写操作 - 二进制文件的处理 - 对象序列化和反序列化 - JSON、XML等数据格式的处理 - 异步文件操作 - 文件监控和事件处理

1. 文件和目录操作基础

1.1 File和Directory类

using System;
using System.IO;
using System.Linq;

public class FileDirectoryBasics
{
    public static void DemonstrateFileDirectoryOperations()
    {
        Console.WriteLine("\n=== 文件和目录操作演示 ===");
        
        Console.WriteLine("\n--- 目录操作 ---");
        DirectoryOperations();
        
        Console.WriteLine("\n--- 文件操作 ---");
        FileOperations();
        
        Console.WriteLine("\n--- 路径操作 ---");
        PathOperations();
        
        Console.WriteLine("\n--- 文件信息获取 ---");
        FileInfoOperations();
    }
    
    private static void DirectoryOperations()
    {
        string testDir = Path.Combine(Path.GetTempPath(), "TestDirectory");
        string subDir = Path.Combine(testDir, "SubDirectory");
        
        try
        {
            // 创建目录
            if (!Directory.Exists(testDir))
            {
                Directory.CreateDirectory(testDir);
                Console.WriteLine($"创建目录: {testDir}");
            }
            
            // 创建子目录
            Directory.CreateDirectory(subDir);
            Console.WriteLine($"创建子目录: {subDir}");
            
            // 获取目录信息
            var dirInfo = new DirectoryInfo(testDir);
            Console.WriteLine($"目录名称: {dirInfo.Name}");
            Console.WriteLine($"完整路径: {dirInfo.FullName}");
            Console.WriteLine($"创建时间: {dirInfo.CreationTime}");
            Console.WriteLine($"最后访问时间: {dirInfo.LastAccessTime}");
            
            // 列出目录内容
            Console.WriteLine("\n目录内容:");
            foreach (var dir in Directory.GetDirectories(testDir))
            {
                Console.WriteLine($"  目录: {Path.GetFileName(dir)}");
            }
            
            // 创建一些测试文件
            for (int i = 1; i <= 3; i++)
            {
                string fileName = Path.Combine(testDir, $"test{i}.txt");
                File.WriteAllText(fileName, $"这是测试文件 {i}");
            }
            
            foreach (var file in Directory.GetFiles(testDir))
            {
                Console.WriteLine($"  文件: {Path.GetFileName(file)}");
            }
            
            // 递归获取所有文件
            Console.WriteLine("\n递归获取所有文件:");
            var allFiles = Directory.GetFiles(testDir, "*.*", SearchOption.AllDirectories);
            foreach (var file in allFiles)
            {
                Console.WriteLine($"  {file}");
            }
            
            // 使用模式匹配
            Console.WriteLine("\n.txt文件:");
            var txtFiles = Directory.GetFiles(testDir, "*.txt", SearchOption.AllDirectories);
            foreach (var file in txtFiles)
            {
                Console.WriteLine($"  {Path.GetFileName(file)}");
            }
        }
        finally
        {
            // 清理测试目录
            if (Directory.Exists(testDir))
            {
                Directory.Delete(testDir, true);
                Console.WriteLine($"\n删除测试目录: {testDir}");
            }
        }
    }
    
    private static void FileOperations()
    {
        string testFile = Path.Combine(Path.GetTempPath(), "test.txt");
        
        try
        {
            // 创建文件
            File.WriteAllText(testFile, "Hello, World!");
            Console.WriteLine($"创建文件: {testFile}");
            
            // 检查文件是否存在
            if (File.Exists(testFile))
            {
                Console.WriteLine("文件存在");
                
                // 读取文件内容
                string content = File.ReadAllText(testFile);
                Console.WriteLine($"文件内容: {content}");
                
                // 追加内容
                File.AppendAllText(testFile, "\n追加的内容");
                
                // 再次读取
                content = File.ReadAllText(testFile);
                Console.WriteLine($"追加后内容: {content}");
                
                // 获取文件属性
                var attributes = File.GetAttributes(testFile);
                Console.WriteLine($"文件属性: {attributes}");
                
                // 获取文件时间信息
                Console.WriteLine($"创建时间: {File.GetCreationTime(testFile)}");
                Console.WriteLine($"最后写入时间: {File.GetLastWriteTime(testFile)}");
                Console.WriteLine($"最后访问时间: {File.GetLastAccessTime(testFile)}");
            }
            
            // 复制文件
            string copyFile = Path.Combine(Path.GetTempPath(), "test_copy.txt");
            File.Copy(testFile, copyFile, true);
            Console.WriteLine($"复制文件到: {copyFile}");
            
            // 移动文件
            string moveFile = Path.Combine(Path.GetTempPath(), "test_moved.txt");
            File.Move(copyFile, moveFile);
            Console.WriteLine($"移动文件到: {moveFile}");
            
            // 删除文件
            File.Delete(moveFile);
            Console.WriteLine($"删除文件: {moveFile}");
        }
        finally
        {
            // 清理
            if (File.Exists(testFile))
            {
                File.Delete(testFile);
            }
        }
    }
    
    private static void PathOperations()
    {
        string filePath = @"C:\Users\Username\Documents\test.txt";
        
        Console.WriteLine($"原始路径: {filePath}");
        Console.WriteLine($"目录名: {Path.GetDirectoryName(filePath)}");
        Console.WriteLine($"文件名: {Path.GetFileName(filePath)}");
        Console.WriteLine($"文件名(无扩展名): {Path.GetFileNameWithoutExtension(filePath)}");
        Console.WriteLine($"扩展名: {Path.GetExtension(filePath)}");
        Console.WriteLine($"根目录: {Path.GetPathRoot(filePath)}");
        
        // 路径组合
        string combinedPath = Path.Combine("C:", "Users", "Username", "Documents", "test.txt");
        Console.WriteLine($"组合路径: {combinedPath}");
        
        // 获取临时路径
        Console.WriteLine($"临时目录: {Path.GetTempPath()}");
        Console.WriteLine($"临时文件名: {Path.GetTempFileName()}");
        
        // 路径验证
        Console.WriteLine($"是否为绝对路径: {Path.IsPathRooted(filePath)}");
        
        // 获取相对路径
        string relativePath = Path.GetRelativePath(@"C:\Users", filePath);
        Console.WriteLine($"相对路径: {relativePath}");
        
        // 获取完整路径
        string fullPath = Path.GetFullPath("test.txt");
        Console.WriteLine($"完整路径: {fullPath}");
    }
    
    private static void FileInfoOperations()
    {
        string testFile = Path.Combine(Path.GetTempPath(), "fileinfo_test.txt");
        
        try
        {
            // 创建测试文件
            File.WriteAllText(testFile, "FileInfo测试内容\n这是第二行");
            
            var fileInfo = new FileInfo(testFile);
            
            Console.WriteLine($"文件名: {fileInfo.Name}");
            Console.WriteLine($"完整路径: {fileInfo.FullName}");
            Console.WriteLine($"目录: {fileInfo.DirectoryName}");
            Console.WriteLine($"大小: {fileInfo.Length} 字节");
            Console.WriteLine($"创建时间: {fileInfo.CreationTime}");
            Console.WriteLine($"最后修改时间: {fileInfo.LastWriteTime}");
            Console.WriteLine($"最后访问时间: {fileInfo.LastAccessTime}");
            Console.WriteLine($"属性: {fileInfo.Attributes}");
            Console.WriteLine($"是否只读: {fileInfo.IsReadOnly}");
            Console.WriteLine($"是否存在: {fileInfo.Exists}");
            
            // 使用FileInfo进行操作
            var copyInfo = fileInfo.CopyTo(Path.Combine(Path.GetTempPath(), "fileinfo_copy.txt"), true);
            Console.WriteLine($"复制到: {copyInfo.FullName}");
            
            // 清理
            copyInfo.Delete();
        }
        finally
        {
            if (File.Exists(testFile))
            {
                File.Delete(testFile);
            }
        }
    }
}

实践练习

练习1:配置管理系统

using System;
using System.IO;
using System.Text.Json;
using System.Text.Json.Serialization;

// 配置数据模型
public class ApplicationConfig
{
    public DatabaseConfig Database { get; set; } = new();
    public LoggingConfig Logging { get; set; } = new();
    public ApiConfig Api { get; set; } = new();
    public Dictionary<string, object> CustomSettings { get; set; } = new();
}

public class DatabaseConfig
{
    public string ConnectionString { get; set; } = "";
    public int MaxConnections { get; set; } = 100;
    public TimeSpan CommandTimeout { get; set; } = TimeSpan.FromSeconds(30);
}

public class LoggingConfig
{
    public string Level { get; set; } = "Information";
    public string FilePath { get; set; } = "logs/app.log";
    public long MaxFileSize { get; set; } = 10 * 1024 * 1024; // 10MB
}

public class ApiConfig
{
    public string BaseUrl { get; set; } = "https://api.example.com";
    public string ApiKey { get; set; } = "";
    public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(30);
}

// 配置管理器
public class ConfigurationManager
{
    private readonly string _configPath;
    private readonly JsonSerializerOptions _jsonOptions;
    private ApplicationConfig _config;
    private readonly FileSystemWatcher _watcher;
    
    public event Action<ApplicationConfig> ConfigChanged;
    
    public ConfigurationManager(string configPath = "appsettings.json")
    {
        _configPath = configPath;
        _jsonOptions = new JsonSerializerOptions
        {
            WriteIndented = true,
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            Converters = { new JsonStringEnumConverter(), new TimeSpanJsonConverter() }
        };
        
        // 监听配置文件变化
        _watcher = new FileSystemWatcher(Path.GetDirectoryName(_configPath) ?? ".", Path.GetFileName(_configPath));
        _watcher.Changed += OnConfigFileChanged;
        _watcher.EnableRaisingEvents = true;
    }
    
    public async Task<ApplicationConfig> LoadConfigAsync()
    {
        if (!File.Exists(_configPath))
        {
            _config = new ApplicationConfig();
            await SaveConfigAsync(_config);
            return _config;
        }
        
        var json = await File.ReadAllTextAsync(_configPath);
        _config = JsonSerializer.Deserialize<ApplicationConfig>(json, _jsonOptions);
        return _config;
    }
    
    public async Task SaveConfigAsync(ApplicationConfig config)
    {
        _config = config;
        var json = JsonSerializer.Serialize(config, _jsonOptions);
        await FileOperationBestPractices.SafeWriteAllTextAsync(_configPath, json);
    }
    
    public T GetSection<T>(string sectionName) where T : new()
    {
        if (_config == null)
            throw new InvalidOperationException("Configuration not loaded");
        
        var property = typeof(ApplicationConfig).GetProperty(sectionName);
        return property?.GetValue(_config) is T value ? value : new T();
    }
    
    private async void OnConfigFileChanged(object sender, FileSystemEventArgs e)
    {
        try
        {
            await Task.Delay(100); // 防止文件被锁定
            var newConfig = await LoadConfigAsync();
            ConfigChanged?.Invoke(newConfig);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error reloading config: {ex.Message}");
        }
    }
    
    public void Dispose()
    {
        _watcher?.Dispose();
    }
}

// TimeSpan的JSON转换器
public class TimeSpanJsonConverter : JsonConverter<TimeSpan>
{
    public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return TimeSpan.Parse(reader.GetString());
    }
    
    public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString());
    }
}

练习2:数据备份和恢复系统

using System;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Text.Json;

// 备份元数据
public class BackupMetadata
{
    public string BackupId { get; set; } = Guid.NewGuid().ToString();
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    public string Description { get; set; } = "";
    public long OriginalSize { get; set; }
    public long CompressedSize { get; set; }
    public string CheckSum { get; set; } = "";
    public List<string> Files { get; set; } = new();
}

// 备份系统
public class BackupSystem
{
    private readonly string _backupDirectory;
    
    public BackupSystem(string backupDirectory = "backups")
    {
        _backupDirectory = backupDirectory;
        Directory.CreateDirectory(_backupDirectory);
    }
    
    // 创建备份
    public async Task<string> CreateBackupAsync(string sourceDirectory, string description = "")
    {
        var backupId = Guid.NewGuid().ToString();
        var backupPath = Path.Combine(_backupDirectory, $"{backupId}.zip");
        var metadataPath = Path.Combine(_backupDirectory, $"{backupId}.metadata.json");
        
        var metadata = new BackupMetadata
        {
            BackupId = backupId,
            Description = description
        };
        
        // 计算原始大小
        var files = Directory.GetFiles(sourceDirectory, "*", SearchOption.AllDirectories);
        metadata.OriginalSize = files.Sum(f => new FileInfo(f).Length);
        metadata.Files = files.Select(f => Path.GetRelativePath(sourceDirectory, f)).ToList();
        
        // 创建压缩备份
        using (var zipStream = new FileStream(backupPath, FileMode.Create))
        using (var archive = new ZipArchive(zipStream, ZipArchiveMode.Create))
        {
            foreach (var file in files)
            {
                var relativePath = Path.GetRelativePath(sourceDirectory, file);
                var entry = archive.CreateEntry(relativePath);
                
                using var entryStream = entry.Open();
                using var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
                await fileStream.CopyToAsync(entryStream);
            }
        }
        
        // 计算压缩后大小和校验和
        var backupInfo = new FileInfo(backupPath);
        metadata.CompressedSize = backupInfo.Length;
        metadata.CheckSum = await ComputeFileHashAsync(backupPath);
        
        // 保存元数据
        var metadataJson = JsonSerializer.Serialize(metadata, new JsonSerializerOptions { WriteIndented = true });
        await File.WriteAllTextAsync(metadataPath, metadataJson);
        
        return backupId;
    }
    
    // 恢复备份
    public async Task RestoreBackupAsync(string backupId, string targetDirectory)
    {
        var backupPath = Path.Combine(_backupDirectory, $"{backupId}.zip");
        var metadataPath = Path.Combine(_backupDirectory, $"{backupId}.metadata.json");
        
        if (!File.Exists(backupPath) || !File.Exists(metadataPath))
            throw new FileNotFoundException($"Backup {backupId} not found");
        
        // 验证备份完整性
        var metadataJson = await File.ReadAllTextAsync(metadataPath);
        var metadata = JsonSerializer.Deserialize<BackupMetadata>(metadataJson);
        
        var currentHash = await ComputeFileHashAsync(backupPath);
        if (currentHash != metadata.CheckSum)
            throw new InvalidDataException("Backup file is corrupted");
        
        // 创建目标目录
        Directory.CreateDirectory(targetDirectory);
        
        // 解压备份
        using var zipStream = new FileStream(backupPath, FileMode.Open, FileAccess.Read);
        using var archive = new ZipArchive(zipStream, ZipArchiveMode.Read);
        
        foreach (var entry in archive.Entries)
        {
            var targetPath = Path.Combine(targetDirectory, entry.FullName);
            var targetDir = Path.GetDirectoryName(targetPath);
            
            if (!string.IsNullOrEmpty(targetDir))
                Directory.CreateDirectory(targetDir);
            
            using var entryStream = entry.Open();
            using var targetStream = new FileStream(targetPath, FileMode.Create);
            await entryStream.CopyToAsync(targetStream);
        }
    }
    
    // 列出所有备份
    public async Task<List<BackupMetadata>> ListBackupsAsync()
    {
        var backups = new List<BackupMetadata>();
        var metadataFiles = Directory.GetFiles(_backupDirectory, "*.metadata.json");
        
        foreach (var file in metadataFiles)
        {
            try
            {
                var json = await File.ReadAllTextAsync(file);
                var metadata = JsonSerializer.Deserialize<BackupMetadata>(json);
                backups.Add(metadata);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error reading metadata {file}: {ex.Message}");
            }
        }
        
        return backups.OrderByDescending(b => b.CreatedAt).ToList();
    }
    
    // 删除备份
    public async Task DeleteBackupAsync(string backupId)
    {
        var backupPath = Path.Combine(_backupDirectory, $"{backupId}.zip");
        var metadataPath = Path.Combine(_backupDirectory, $"{backupId}.metadata.json");
        
        if (File.Exists(backupPath))
            File.Delete(backupPath);
        
        if (File.Exists(metadataPath))
            File.Delete(metadataPath);
    }
    
    // 计算文件哈希
    private async Task<string> ComputeFileHashAsync(string filePath)
    {
        using var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
        using var sha256 = SHA256.Create();
        var hash = await sha256.ComputeHashAsync(stream);
        return Convert.ToHexString(hash);
    }
}

// 使用示例
public class BackupDemo
{
    public static async Task DemoBackupSystem()
    {
        var backupSystem = new BackupSystem();
        
        // 创建备份
        var backupId = await backupSystem.CreateBackupAsync(
            @"C:\MyProject", 
            "Project backup before major refactoring");
        
        Console.WriteLine($"Backup created: {backupId}");
        
        // 列出备份
        var backups = await backupSystem.ListBackupsAsync();
        foreach (var backup in backups)
        {
            Console.WriteLine($"Backup: {backup.BackupId}");
            Console.WriteLine($"  Created: {backup.CreatedAt}");
            Console.WriteLine($"  Description: {backup.Description}");
            Console.WriteLine($"  Size: {backup.OriginalSize:N0} -> {backup.CompressedSize:N0} bytes");
            Console.WriteLine($"  Compression: {(1 - (double)backup.CompressedSize / backup.OriginalSize):P1}");
        }
        
        // 恢复备份
        await backupSystem.RestoreBackupAsync(backupId, @"C:\RestoredProject");
        Console.WriteLine("Backup restored successfully");
    }
}

本章总结

在本章中,我们深入学习了C#中的文件I/O和序列化技术:

核心概念

  • 文件和目录操作:掌握了File、Directory、Path、FileInfo等类的使用
  • 流操作:理解了FileStream、MemoryStream、BufferedStream的特点和应用场景
  • 文本读写:学会了StreamWriter/Reader、StringWriter/Reader的使用和编码处理
  • 二进制文件:掌握了BinaryWriter/Reader进行二进制数据读写

序列化技术

  • JSON序列化:学习了System.Text.Json和Newtonsoft.Json的使用
  • XML序列化:掌握了XmlSerializer的基本和高级用法
  • 二进制序列化:了解了现代二进制序列化方案如MessagePack
  • 自定义序列化:学会了创建自定义转换器和控制序列化行为

高级技术

  • 流式序列化:掌握了处理大量数据的流式读写技术
  • 性能优化:学习了ArrayPool、预编译序列化器等优化技术
  • 最佳实践:掌握了安全文件操作、错误处理、并发控制等实践

实际应用

  • 配置管理系统:实现了完整的配置文件管理和监听机制
  • 备份恢复系统:构建了具有压缩、校验、元数据管理的备份系统

重要技能

  1. 选择合适的I/O类和序列化方案
  2. 处理大文件和流式数据
  3. 实现高性能的文件操作
  4. 设计健壮的错误处理机制
  5. 应用安全的文件操作模式

文件I/O和序列化是应用程序与外部数据交互的基础,掌握这些技术对于构建实用的应用程序至关重要。


下一章预告:第17章将介绍网络编程,包括HTTP客户端、TCP/UDP通信、WebSocket等网络通信技术。

1.2 DriveInfo和磁盘信息

public class DriveInfoDemo
{
    public static void DemonstrateDriveInfo()
    {
        Console.WriteLine("\n=== 磁盘信息演示 ===");
        
        // 获取所有驱动器
        DriveInfo[] drives = DriveInfo.GetDrives();
        
        Console.WriteLine($"系统中共有 {drives.Length} 个驱动器:");
        
        foreach (DriveInfo drive in drives)
        {
            Console.WriteLine($"\n驱动器: {drive.Name}");
            Console.WriteLine($"类型: {drive.DriveType}");
            
            if (drive.IsReady)
            {
                Console.WriteLine($"标签: {drive.VolumeLabel}");
                Console.WriteLine($"文件系统: {drive.DriveFormat}");
                Console.WriteLine($"总大小: {FormatBytes(drive.TotalSize)}");
                Console.WriteLine($"可用空间: {FormatBytes(drive.AvailableFreeSpace)}");
                Console.WriteLine($"空闲空间: {FormatBytes(drive.TotalFreeSpace)}");
                
                double usedPercentage = (double)(drive.TotalSize - drive.TotalFreeSpace) / drive.TotalSize * 100;
                Console.WriteLine($"使用率: {usedPercentage:F2}%");
                
                // 根目录信息
                var rootDir = drive.RootDirectory;
                Console.WriteLine($"根目录: {rootDir.FullName}");
                
                try
                {
                    var subDirs = rootDir.GetDirectories().Take(5);
                    Console.WriteLine("根目录下的前5个子目录:");
                    foreach (var dir in subDirs)
                    {
                        Console.WriteLine($"  {dir.Name}");
                    }
                }
                catch (UnauthorizedAccessException)
                {
                    Console.WriteLine("  无权限访问根目录内容");
                }
            }
            else
            {
                Console.WriteLine("驱动器未就绪");
            }
        }
        
        // 获取特定驱动器信息
        Console.WriteLine("\n--- 当前目录所在驱动器信息 ---");
        string currentDrive = Path.GetPathRoot(Environment.CurrentDirectory);
        DriveInfo currentDriveInfo = new DriveInfo(currentDrive);
        
        if (currentDriveInfo.IsReady)
        {
            Console.WriteLine($"当前驱动器: {currentDriveInfo.Name}");
            Console.WriteLine($"可用空间: {FormatBytes(currentDriveInfo.AvailableFreeSpace)}");
            Console.WriteLine($"总空间: {FormatBytes(currentDriveInfo.TotalSize)}");
            
            // 检查磁盘空间是否充足
            long requiredSpace = 1024 * 1024 * 100; // 100MB
            bool hasEnoughSpace = currentDriveInfo.AvailableFreeSpace > requiredSpace;
            Console.WriteLine($"是否有足够空间(100MB): {hasEnoughSpace}");
        }
    }
    
    private static string FormatBytes(long bytes)
    {
        string[] suffixes = { "B", "KB", "MB", "GB", "TB", "PB" };
        int counter = 0;
        decimal number = bytes;
        
        while (Math.Round(number / 1024) >= 1)
        {
            number /= 1024;
            counter++;
        }
        
        return $"{number:N2} {suffixes[counter]}";
    }
}

2. 流(Stream)操作

2.1 Stream基础概念

using System.Text;

public class StreamBasics
{
    public static void DemonstrateStreamOperations()
    {
        Console.WriteLine("\n=== 流操作演示 ===");
        
        Console.WriteLine("\n--- FileStream操作 ---");
        FileStreamOperations();
        
        Console.WriteLine("\n--- MemoryStream操作 ---");
        MemoryStreamOperations();
        
        Console.WriteLine("\n--- BufferedStream操作 ---");
        BufferedStreamOperations();
        
        Console.WriteLine("\n--- 流的复制和转换 ---");
        StreamCopyAndConversion();
    }
    
    private static void FileStreamOperations()
    {
        string testFile = Path.Combine(Path.GetTempPath(), "stream_test.txt");
        
        try
        {
            // 写入数据到文件流
            using (var fileStream = new FileStream(testFile, FileMode.Create, FileAccess.Write))
            {
                string text = "Hello, FileStream!\n这是中文测试";
                byte[] data = Encoding.UTF8.GetBytes(text);
                
                fileStream.Write(data, 0, data.Length);
                Console.WriteLine($"写入 {data.Length} 字节到文件");
                
                // 获取流信息
                Console.WriteLine($"流位置: {fileStream.Position}");
                Console.WriteLine($"流长度: {fileStream.Length}");
                Console.WriteLine($"可读: {fileStream.CanRead}");
                Console.WriteLine($"可写: {fileStream.CanWrite}");
                Console.WriteLine($"可定位: {fileStream.CanSeek}");
            }
            
            // 从文件流读取数据
            using (var fileStream = new FileStream(testFile, FileMode.Open, FileAccess.Read))
            {
                byte[] buffer = new byte[fileStream.Length];
                int bytesRead = fileStream.Read(buffer, 0, buffer.Length);
                
                string text = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                Console.WriteLine($"读取 {bytesRead} 字节: {text}");
                
                // 流定位操作
                fileStream.Seek(0, SeekOrigin.Begin);
                Console.WriteLine($"重置到开始位置: {fileStream.Position}");
                
                // 读取前5个字节
                byte[] firstBytes = new byte[5];
                fileStream.Read(firstBytes, 0, 5);
                string firstText = Encoding.UTF8.GetString(firstBytes);
                Console.WriteLine($"前5个字节: {firstText}");
            }
        }
        finally
        {
            if (File.Exists(testFile))
            {
                File.Delete(testFile);
            }
        }
    }
    
    private static void MemoryStreamOperations()
    {
        // 创建内存流
        using (var memoryStream = new MemoryStream())
        {
            // 写入数据
            string text = "MemoryStream测试数据";
            byte[] data = Encoding.UTF8.GetBytes(text);
            
            memoryStream.Write(data, 0, data.Length);
            Console.WriteLine($"写入 {data.Length} 字节到内存流");
            
            // 获取内存流的字节数组
            byte[] streamData = memoryStream.ToArray();
            Console.WriteLine($"内存流数据: {Encoding.UTF8.GetString(streamData)}");
            
            // 重置位置并读取
            memoryStream.Seek(0, SeekOrigin.Begin);
            byte[] readBuffer = new byte[memoryStream.Length];
            int bytesRead = memoryStream.Read(readBuffer, 0, readBuffer.Length);
            
            Console.WriteLine($"读取 {bytesRead} 字节: {Encoding.UTF8.GetString(readBuffer)}");
            
            // 追加数据
            memoryStream.Seek(0, SeekOrigin.End);
            string appendText = "\n追加的数据";
            byte[] appendData = Encoding.UTF8.GetBytes(appendText);
            memoryStream.Write(appendData, 0, appendData.Length);
            
            Console.WriteLine($"追加后的数据: {Encoding.UTF8.GetString(memoryStream.ToArray())}");
        }
        
        // 从字节数组创建内存流
        byte[] initialData = Encoding.UTF8.GetBytes("初始数据");
        using (var memoryStream = new MemoryStream(initialData))
        {
            Console.WriteLine($"\n从字节数组创建的内存流长度: {memoryStream.Length}");
            
            // 读取数据
            memoryStream.Seek(0, SeekOrigin.Begin);
            byte[] buffer = new byte[memoryStream.Length];
            memoryStream.Read(buffer, 0, buffer.Length);
            
            Console.WriteLine($"读取的数据: {Encoding.UTF8.GetString(buffer)}");
        }
    }
    
    private static void BufferedStreamOperations()
    {
        string testFile = Path.Combine(Path.GetTempPath(), "buffered_test.txt");
        
        try
        {
            // 使用缓冲流写入
            using (var fileStream = new FileStream(testFile, FileMode.Create))
            using (var bufferedStream = new BufferedStream(fileStream, 4096))
            {
                for (int i = 0; i < 1000; i++)
                {
                    string line = $"这是第 {i + 1} 行数据\n";
                    byte[] data = Encoding.UTF8.GetBytes(line);
                    bufferedStream.Write(data, 0, data.Length);
                }
                
                // 强制刷新缓冲区
                bufferedStream.Flush();
                Console.WriteLine("使用缓冲流写入1000行数据");
            }
            
            // 使用缓冲流读取
            using (var fileStream = new FileStream(testFile, FileMode.Open))
            using (var bufferedStream = new BufferedStream(fileStream, 4096))
            {
                byte[] buffer = new byte[1024];
                int totalBytesRead = 0;
                int bytesRead;
                
                while ((bytesRead = bufferedStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    totalBytesRead += bytesRead;
                }
                
                Console.WriteLine($"使用缓冲流读取了 {totalBytesRead} 字节");
            }
            
            // 性能对比
            Console.WriteLine("\n性能对比:");
            CompareStreamPerformance(testFile);
        }
        finally
        {
            if (File.Exists(testFile))
            {
                File.Delete(testFile);
            }
        }
    }
    
    private static void CompareStreamPerformance(string testFile)
    {
        var stopwatch = System.Diagnostics.Stopwatch.StartNew();
        
        // 直接使用FileStream
        stopwatch.Restart();
        using (var fileStream = new FileStream(testFile, FileMode.Open))
        {
            byte[] buffer = new byte[1];
            while (fileStream.Read(buffer, 0, 1) > 0)
            {
                // 逐字节读取
            }
        }
        stopwatch.Stop();
        long directStreamTime = stopwatch.ElapsedMilliseconds;
        
        // 使用BufferedStream
        stopwatch.Restart();
        using (var fileStream = new FileStream(testFile, FileMode.Open))
        using (var bufferedStream = new BufferedStream(fileStream))
        {
            byte[] buffer = new byte[1];
            while (bufferedStream.Read(buffer, 0, 1) > 0)
            {
                // 逐字节读取
            }
        }
        stopwatch.Stop();
        long bufferedStreamTime = stopwatch.ElapsedMilliseconds;
        
        Console.WriteLine($"直接FileStream时间: {directStreamTime}ms");
        Console.WriteLine($"BufferedStream时间: {bufferedStreamTime}ms");
        Console.WriteLine($"性能提升: {(double)directStreamTime / Math.Max(bufferedStreamTime, 1):F2}x");
    }
    
    private static void StreamCopyAndConversion()
    {
        // 流之间的复制
        string sourceText = "这是要复制的数据\n包含多行内容\n用于测试流复制功能";
        
        using (var sourceStream = new MemoryStream(Encoding.UTF8.GetBytes(sourceText)))
        using (var destinationStream = new MemoryStream())
        {
            // 复制流
            sourceStream.CopyTo(destinationStream);
            
            Console.WriteLine($"源流长度: {sourceStream.Length}");
            Console.WriteLine($"目标流长度: {destinationStream.Length}");
            Console.WriteLine($"复制的数据: {Encoding.UTF8.GetString(destinationStream.ToArray())}");
        }
        
        // 使用缓冲区复制
        using (var sourceStream = new MemoryStream(Encoding.UTF8.GetBytes(sourceText)))
        using (var destinationStream = new MemoryStream())
        {
            byte[] buffer = new byte[1024];
            int bytesRead;
            int totalBytes = 0;
            
            sourceStream.Seek(0, SeekOrigin.Begin);
            
            while ((bytesRead = sourceStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                destinationStream.Write(buffer, 0, bytesRead);
                totalBytes += bytesRead;
            }
            
            Console.WriteLine($"\n手动复制了 {totalBytes} 字节");
            Console.WriteLine($"复制结果: {Encoding.UTF8.GetString(destinationStream.ToArray())}");
        }
    }
}

2.2 文本读写器

public class TextReaderWriterDemo
{
    public static void DemonstrateTextReaderWriter()
    {
        Console.WriteLine("\n=== 文本读写器演示 ===");
        
        Console.WriteLine("\n--- StreamWriter和StreamReader ---");
        StreamWriterReaderDemo();
        
        Console.WriteLine("\n--- StringWriter和StringReader ---");
        StringWriterReaderDemo();
        
        Console.WriteLine("\n--- 编码处理 ---");
        EncodingDemo();
        
        Console.WriteLine("\n--- 大文件处理 ---");
        LargeFileDemo();
    }
    
    private static void StreamWriterReaderDemo()
    {
        string testFile = Path.Combine(Path.GetTempPath(), "text_test.txt");
        
        try
        {
            // 使用StreamWriter写入文本
            using (var writer = new StreamWriter(testFile, false, Encoding.UTF8))
            {
                writer.WriteLine("第一行文本");
                writer.WriteLine("第二行文本");
                writer.Write("不换行的文本");
                writer.Write(" 继续在同一行");
                writer.WriteLine(); // 手动换行
                writer.WriteLine($"当前时间: {DateTime.Now}");
                
                // 写入格式化文本
                writer.WriteLine("格式化文本: {0}, {1:F2}", "测试", 123.456);
                
                // 自动刷新
                writer.AutoFlush = true;
                writer.WriteLine("自动刷新的文本");
            }
            
            Console.WriteLine($"文本已写入到: {testFile}");
            
            // 使用StreamReader读取文本
            using (var reader = new StreamReader(testFile, Encoding.UTF8))
            {
                Console.WriteLine("\n逐行读取:");
                string line;
                int lineNumber = 1;
                
                while ((line = reader.ReadLine()) != null)
                {
                    Console.WriteLine($"第{lineNumber}行: {line}");
                    lineNumber++;
                }
            }
            
            // 一次性读取所有内容
            using (var reader = new StreamReader(testFile, Encoding.UTF8))
            {
                string allContent = reader.ReadToEnd();
                Console.WriteLine($"\n全部内容:\n{allContent}");
            }
            
            // 读取指定字符数
            using (var reader = new StreamReader(testFile, Encoding.UTF8))
            {
                char[] buffer = new char[10];
                int charsRead = reader.Read(buffer, 0, buffer.Length);
                Console.WriteLine($"\n读取前{charsRead}个字符: {new string(buffer, 0, charsRead)}");
            }
        }
        finally
        {
            if (File.Exists(testFile))
            {
                File.Delete(testFile);
            }
        }
    }
    
    private static void StringWriterReaderDemo()
    {
        // StringWriter示例
        using (var stringWriter = new StringWriter())
        {
            stringWriter.WriteLine("使用StringWriter");
            stringWriter.WriteLine("写入到内存中的字符串");
            stringWriter.Write("数字: ");
            stringWriter.WriteLine(42);
            stringWriter.WriteLine($"时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
            
            string result = stringWriter.ToString();
            Console.WriteLine($"StringWriter结果:\n{result}");
        }
        
        // StringReader示例
        string text = "第一行\n第二行\n第三行\n最后一行";
        using (var stringReader = new StringReader(text))
        {
            Console.WriteLine("\nStringReader逐行读取:");
            string line;
            int lineNumber = 1;
            
            while ((line = stringReader.ReadLine()) != null)
            {
                Console.WriteLine($"行{lineNumber}: {line}");
                lineNumber++;
            }
        }
        
        // 使用StringReader读取字符
        using (var stringReader = new StringReader(text))
        {
            Console.WriteLine("\n逐字符读取前10个字符:");
            for (int i = 0; i < 10; i++)
            {
                int ch = stringReader.Read();
                if (ch == -1) break;
                
                char character = (char)ch;
                Console.Write(character == '\n' ? "\\n" : character.ToString());
            }
            Console.WriteLine();
        }
    }
    
    private static void EncodingDemo()
    {
        string testFile = Path.Combine(Path.GetTempPath(), "encoding_test.txt");
        string testText = "Hello World! 你好世界! こんにちは! 🌍";
        
        try
        {
            // 测试不同编码
            var encodings = new[]
            {
                new { Name = "UTF-8", Encoding = Encoding.UTF8 },
                new { Name = "UTF-16", Encoding = Encoding.Unicode },
                new { Name = "UTF-32", Encoding = Encoding.UTF32 },
                new { Name = "ASCII", Encoding = Encoding.ASCII },
                new { Name = "GBK", Encoding = Encoding.GetEncoding("GBK") }
            };
            
            foreach (var enc in encodings)
            {
                try
                {
                    // 写入文件
                    using (var writer = new StreamWriter(testFile, false, enc.Encoding))
                    {
                        writer.WriteLine(testText);
                    }
                    
                    // 读取文件
                    using (var reader = new StreamReader(testFile, enc.Encoding))
                    {
                        string readText = reader.ReadLine();
                        Console.WriteLine($"{enc.Name}: {readText}");
                        
                        // 检查是否正确读取
                        bool isCorrect = readText == testText;
                        Console.WriteLine($"  编码正确: {isCorrect}");
                    }
                    
                    // 显示文件大小
                    var fileInfo = new FileInfo(testFile);
                    Console.WriteLine($"  文件大小: {fileInfo.Length} 字节\n");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"{enc.Name}: 编码错误 - {ex.Message}\n");
                }
            }
            
            // 自动检测编码
            Console.WriteLine("--- 自动检测编码 ---");
            
            // 写入UTF-8文件(带BOM)
            using (var writer = new StreamWriter(testFile, false, new UTF8Encoding(true)))
            {
                writer.WriteLine(testText);
            }
            
            // 自动检测编码读取
            using (var reader = new StreamReader(testFile, true))
            {
                string content = reader.ReadLine();
                Console.WriteLine($"自动检测编码: {reader.CurrentEncoding.EncodingName}");
                Console.WriteLine($"读取内容: {content}");
            }
        }
        finally
        {
            if (File.Exists(testFile))
            {
                File.Delete(testFile);
            }
        }
    }
    
    private static void LargeFileDemo()
    {
        string largeFile = Path.Combine(Path.GetTempPath(), "large_file.txt");
        
        try
        {
            // 创建大文件
            Console.WriteLine("创建大文件...");
            using (var writer = new StreamWriter(largeFile))
            {
                for (int i = 1; i <= 100000; i++)
                {
                    writer.WriteLine($"这是第 {i} 行,包含一些测试数据 - {DateTime.Now.Ticks}");
                    
                    if (i % 10000 == 0)
                    {
                        Console.WriteLine($"已写入 {i} 行");
                    }
                }
            }
            
            var fileInfo = new FileInfo(largeFile);
            Console.WriteLine($"大文件创建完成,大小: {fileInfo.Length / 1024 / 1024:F2} MB");
            
            // 高效读取大文件
            Console.WriteLine("\n高效读取大文件前10行:");
            using (var reader = new StreamReader(largeFile))
            {
                for (int i = 0; i < 10; i++)
                {
                    string line = reader.ReadLine();
                    if (line == null) break;
                    Console.WriteLine($"  {line}");
                }
            }
            
            // 搜索特定内容
            Console.WriteLine("\n搜索包含'50000'的行:");
            using (var reader = new StreamReader(largeFile))
            {
                string line;
                int lineNumber = 0;
                
                while ((line = reader.ReadLine()) != null)
                {
                    lineNumber++;
                    if (line.Contains("50000"))
                    {
                        Console.WriteLine($"  第{lineNumber}行: {line}");
                        break;
                    }
                }
            }
            
            // 统计行数
            Console.WriteLine("\n统计文件行数:");
            int totalLines = 0;
            using (var reader = new StreamReader(largeFile))
            {
                while (reader.ReadLine() != null)
                {
                    totalLines++;
                }
            }
            Console.WriteLine($"总行数: {totalLines}");
        }
        finally
        {
            if (File.Exists(largeFile))
            {
                File.Delete(largeFile);
                Console.WriteLine("\n清理大文件");
            }
        }
    }
}

3. 二进制文件操作

3.1 BinaryReader和BinaryWriter

public class BinaryFileOperations
{
    public static void DemonstrateBinaryOperations()
    {
        Console.WriteLine("\n=== 二进制文件操作演示 ===");
        
        Console.WriteLine("\n--- 基本二进制读写 ---");
        BasicBinaryOperations();
        
        Console.WriteLine("\n--- 复杂数据结构 ---");
        ComplexDataStructures();
        
        Console.WriteLine("\n--- 二进制文件格式 ---");
        CustomBinaryFormat();
    }
    
    private static void BasicBinaryOperations()
    {
        string binaryFile = Path.Combine(Path.GetTempPath(), "binary_test.dat");
        
        try
        {
            // 写入二进制数据
            using (var fileStream = new FileStream(binaryFile, FileMode.Create))
            using (var writer = new BinaryWriter(fileStream))
            {
                // 写入各种数据类型
                writer.Write(true);                    // bool
                writer.Write((byte)255);               // byte
                writer.Write((short)32767);            // short
                writer.Write(2147483647);              // int
                writer.Write(9223372036854775807L);    // long
                writer.Write(3.14159f);                // float
                writer.Write(2.718281828459045);       // double
                writer.Write('A');                     // char
                writer.Write("Hello, Binary!");       // string
                writer.Write(DateTime.Now.ToBinary()); // DateTime as binary
                
                // 写入字节数组
                byte[] byteArray = { 1, 2, 3, 4, 5 };
                writer.Write(byteArray.Length);
                writer.Write(byteArray);
                
                Console.WriteLine("二进制数据写入完成");
            }
            
            // 读取二进制数据
            using (var fileStream = new FileStream(binaryFile, FileMode.Open))
            using (var reader = new BinaryReader(fileStream))
            {
                Console.WriteLine("\n读取二进制数据:");
                
                bool boolValue = reader.ReadBoolean();
                byte byteValue = reader.ReadByte();
                short shortValue = reader.ReadInt16();
                int intValue = reader.ReadInt32();
                long longValue = reader.ReadInt64();
                float floatValue = reader.ReadSingle();
                double doubleValue = reader.ReadDouble();
                char charValue = reader.ReadChar();
                string stringValue = reader.ReadString();
                DateTime dateTimeValue = DateTime.FromBinary(reader.ReadInt64());
                
                Console.WriteLine($"bool: {boolValue}");
                Console.WriteLine($"byte: {byteValue}");
                Console.WriteLine($"short: {shortValue}");
                Console.WriteLine($"int: {intValue}");
                Console.WriteLine($"long: {longValue}");
                Console.WriteLine($"float: {floatValue}");
                Console.WriteLine($"double: {doubleValue}");
                Console.WriteLine($"char: {charValue}");
                Console.WriteLine($"string: {stringValue}");
                Console.WriteLine($"DateTime: {dateTimeValue}");
                
                // 读取字节数组
                int arrayLength = reader.ReadInt32();
                byte[] readByteArray = reader.ReadBytes(arrayLength);
                Console.WriteLine($"byte array: [{string.Join(", ", readByteArray)}]");
            }
            
            var fileInfo = new FileInfo(binaryFile);
            Console.WriteLine($"\n二进制文件大小: {fileInfo.Length} 字节");
        }
        finally
        {
            if (File.Exists(binaryFile))
            {
                File.Delete(binaryFile);
            }
        }
    }
    
    private static void ComplexDataStructures()
    {
        string dataFile = Path.Combine(Path.GetTempPath(), "complex_data.dat");
        
        // 定义复杂数据结构
        var students = new List<StudentRecord>
        {
            new StudentRecord { Id = 1, Name = "张三", Age = 20, GPA = 3.8, Courses = new[] { "数学", "物理", "编程" } },
            new StudentRecord { Id = 2, Name = "李四", Age = 21, GPA = 3.6, Courses = new[] { "化学", "生物" } },
            new StudentRecord { Id = 3, Name = "王五", Age = 19, GPA = 3.9, Courses = new[] { "历史", "地理", "政治", "语文" } }
        };
        
        try
        {
            // 写入复杂数据结构
            using (var fileStream = new FileStream(dataFile, FileMode.Create))
            using (var writer = new BinaryWriter(fileStream))
            {
                // 写入文件头
                writer.Write("STUDENT_DATA"); // 文件标识
                writer.Write((byte)1);         // 版本号
                writer.Write(students.Count);  // 记录数量
                
                foreach (var student in students)
                {
                    WriteStudentRecord(writer, student);
                }
                
                Console.WriteLine($"写入 {students.Count} 个学生记录");
            }
            
            // 读取复杂数据结构
            using (var fileStream = new FileStream(dataFile, FileMode.Open))
            using (var reader = new BinaryReader(fileStream))
            {
                // 读取文件头
                string fileId = reader.ReadString();
                byte version = reader.ReadByte();
                int recordCount = reader.ReadInt32();
                
                Console.WriteLine($"\n文件标识: {fileId}");
                Console.WriteLine($"版本: {version}");
                Console.WriteLine($"记录数量: {recordCount}");
                
                Console.WriteLine("\n读取学生记录:");
                for (int i = 0; i < recordCount; i++)
                {
                    var student = ReadStudentRecord(reader);
                    Console.WriteLine($"  {student.Id}: {student.Name}, {student.Age}岁, GPA: {student.GPA}");
                    Console.WriteLine($"    课程: {string.Join(", ", student.Courses)}");
                }
            }
        }
        finally
        {
            if (File.Exists(dataFile))
            {
                File.Delete(dataFile);
            }
        }
    }
    
    private static void WriteStudentRecord(BinaryWriter writer, StudentRecord student)
    {
        writer.Write(student.Id);
        writer.Write(student.Name);
        writer.Write(student.Age);
        writer.Write(student.GPA);
        
        // 写入课程数组
        writer.Write(student.Courses.Length);
        foreach (string course in student.Courses)
        {
            writer.Write(course);
        }
    }
    
    private static StudentRecord ReadStudentRecord(BinaryReader reader)
    {
        var student = new StudentRecord
        {
            Id = reader.ReadInt32(),
            Name = reader.ReadString(),
            Age = reader.ReadInt32(),
            GPA = reader.ReadDouble()
        };
        
        // 读取课程数组
        int courseCount = reader.ReadInt32();
        student.Courses = new string[courseCount];
        for (int i = 0; i < courseCount; i++)
        {
            student.Courses[i] = reader.ReadString();
        }
        
        return student;
    }
    
    private static void CustomBinaryFormat()
    {
        string formatFile = Path.Combine(Path.GetTempPath(), "custom_format.dat");
        
        try
        {
            // 创建自定义二进制格式
            using (var fileStream = new FileStream(formatFile, FileMode.Create))
            using (var writer = new BinaryWriter(fileStream))
            {
                // 文件头 (16字节)
                writer.Write(Encoding.ASCII.GetBytes("MYFORMAT"));  // 8字节标识
                writer.Write((ushort)1);                            // 2字节主版本
                writer.Write((ushort)0);                            // 2字节次版本
                writer.Write((uint)0);                              // 4字节保留字段
                
                // 数据块1: 配置信息
                WriteDataBlock(writer, "CONFIG", () =>
                {
                    writer.Write("MyApplication");  // 应用名称
                    writer.Write(true);             // 启用调试
                    writer.Write(1024);             // 缓冲区大小
                });
                
                // 数据块2: 用户数据
                WriteDataBlock(writer, "USERS", () =>
                {
                    var users = new[] { "admin", "user1", "user2" };
                    writer.Write(users.Length);
                    foreach (string user in users)
                    {
                        writer.Write(user);
                        writer.Write(DateTime.Now.ToBinary()); // 创建时间
                    }
                });
                
                // 数据块3: 统计信息
                WriteDataBlock(writer, "STATS", () =>
                {
                    writer.Write(12345L);    // 总访问次数
                    writer.Write(678.9);     // 平均响应时间
                    writer.Write((byte)95);  // 成功率百分比
                });
                
                Console.WriteLine("自定义格式文件创建完成");
            }
            
            // 读取自定义格式
            using (var fileStream = new FileStream(formatFile, FileMode.Open))
            using (var reader = new BinaryReader(fileStream))
            {
                // 读取文件头
                byte[] signature = reader.ReadBytes(8);
                ushort majorVersion = reader.ReadUInt16();
                ushort minorVersion = reader.ReadUInt16();
                uint reserved = reader.ReadUInt32();
                
                string signatureStr = Encoding.ASCII.GetString(signature);
                Console.WriteLine($"\n文件签名: {signatureStr}");
                Console.WriteLine($"版本: {majorVersion}.{minorVersion}");
                
                // 读取数据块
                while (fileStream.Position < fileStream.Length)
                {
                    var (blockType, blockData) = ReadDataBlock(reader);
                    Console.WriteLine($"\n数据块类型: {blockType}");
                    Console.WriteLine($"数据块大小: {blockData.Length} 字节");
                    
                    // 解析特定数据块
                    using (var blockStream = new MemoryStream(blockData))
                    using (var blockReader = new BinaryReader(blockStream))
                    {
                        ParseDataBlock(blockType, blockReader);
                    }
                }
            }
        }
        finally
        {
            if (File.Exists(formatFile))
            {
                File.Delete(formatFile);
            }
        }
    }
    
    private static void WriteDataBlock(BinaryWriter writer, string blockType, Action writeData)
    {
        // 写入块类型 (8字节,不足补0)
        byte[] typeBytes = new byte[8];
        byte[] actualBytes = Encoding.ASCII.GetBytes(blockType);
        Array.Copy(actualBytes, typeBytes, Math.Min(actualBytes.Length, 8));
        writer.Write(typeBytes);
        
        // 使用内存流计算数据大小
        using (var dataStream = new MemoryStream())
        using (var dataWriter = new BinaryWriter(dataStream))
        {
            writeData();
            byte[] data = dataStream.ToArray();
            
            writer.Write((uint)data.Length); // 写入数据大小
            writer.Write(data);              // 写入数据
        }
    }
    
    private static (string BlockType, byte[] Data) ReadDataBlock(BinaryReader reader)
    {
        byte[] typeBytes = reader.ReadBytes(8);
        string blockType = Encoding.ASCII.GetString(typeBytes).TrimEnd('\0');
        
        uint dataSize = reader.ReadUInt32();
        byte[] data = reader.ReadBytes((int)dataSize);
        
        return (blockType, data);
    }
    
    private static void ParseDataBlock(string blockType, BinaryReader reader)
    {
        switch (blockType)
        {
            case "CONFIG":
                string appName = reader.ReadString();
                bool debugEnabled = reader.ReadBoolean();
                int bufferSize = reader.ReadInt32();
                Console.WriteLine($"  应用名称: {appName}");
                Console.WriteLine($"  调试模式: {debugEnabled}");
                Console.WriteLine($"  缓冲区大小: {bufferSize}");
                break;
                
            case "USERS":
                int userCount = reader.ReadInt32();
                Console.WriteLine($"  用户数量: {userCount}");
                for (int i = 0; i < userCount; i++)
                {
                    string userName = reader.ReadString();
                    DateTime createTime = DateTime.FromBinary(reader.ReadInt64());
                    Console.WriteLine($"    {userName} - {createTime:yyyy-MM-dd HH:mm:ss}");
                }
                break;
                
            case "STATS":
                long totalVisits = reader.ReadInt64();
                double avgResponseTime = reader.ReadDouble();
                byte successRate = reader.ReadByte();
                Console.WriteLine($"  总访问次数: {totalVisits}");
                Console.WriteLine($"  平均响应时间: {avgResponseTime}ms");
                Console.WriteLine($"  成功率: {successRate}%");
                break;
                
            default:
                Console.WriteLine($"  未知数据块类型: {blockType}");
                break;
        }
    }
}

// 学生记录数据结构
public class StudentRecord
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public double GPA { get; set; }
    public string[] Courses { get; set; }
}

4. 对象序列化

4.1 JSON序列化

using System.Text.Json;
using System.Text.Json.Serialization;
using Newtonsoft.Json;

public class JsonSerializationDemo
{
    public static void DemonstrateJsonSerialization()
    {
        Console.WriteLine("\n=== JSON序列化演示 ===");
        
        Console.WriteLine("\n--- System.Text.Json ---");
        SystemTextJsonDemo();
        
        Console.WriteLine("\n--- Newtonsoft.Json ---");
        NewtonsoftJsonDemo();
        
        Console.WriteLine("\n--- 复杂对象序列化 ---");
        ComplexObjectSerialization();
        
        Console.WriteLine("\n--- 自定义序列化 ---");
        CustomJsonSerialization();
    }
    
    private static void SystemTextJsonDemo()
    {
        // 创建测试对象
        var person = new Person
        {
            Id = 1,
            Name = "张三",
            Age = 30,
            Email = "zhangsan@example.com",
            BirthDate = new DateTime(1993, 5, 15),
            IsActive = true,
            Tags = new[] { "开发者", "C#", "技术" }
        };
        
        // 序列化为JSON
        var options = new JsonSerializerOptions
        {
            WriteIndented = true,
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
        };
        
        string json = JsonSerializer.Serialize(person, options);
        Console.WriteLine($"序列化结果:\n{json}");
        
        // 反序列化
        Person deserializedPerson = JsonSerializer.Deserialize<Person>(json, options);
        Console.WriteLine($"\n反序列化结果:");
        Console.WriteLine($"ID: {deserializedPerson.Id}");
        Console.WriteLine($"姓名: {deserializedPerson.Name}");
        Console.WriteLine($"年龄: {deserializedPerson.Age}");
        Console.WriteLine($"邮箱: {deserializedPerson.Email}");
        Console.WriteLine($"生日: {deserializedPerson.BirthDate:yyyy-MM-dd}");
        Console.WriteLine($"活跃: {deserializedPerson.IsActive}");
        Console.WriteLine($"标签: {string.Join(", ", deserializedPerson.Tags)}");
        
        // 保存到文件
        string jsonFile = Path.Combine(Path.GetTempPath(), "person.json");
        try
        {
            File.WriteAllText(jsonFile, json);
            Console.WriteLine($"\nJSON已保存到: {jsonFile}");
            
            // 从文件读取
            string fileJson = File.ReadAllText(jsonFile);
            Person filePerson = JsonSerializer.Deserialize<Person>(fileJson, options);
            Console.WriteLine($"从文件读取: {filePerson.Name}");
        }
        finally
        {
            if (File.Exists(jsonFile))
            {
                File.Delete(jsonFile);
            }
        }
    }
    
    private static void NewtonsoftJsonDemo()
    {
        var product = new Product
        {
            Id = 101,
            Name = "笔记本电脑",
            Price = 5999.99m,
            Category = "电子产品",
            InStock = true,
            CreatedAt = DateTime.Now,
            Specifications = new Dictionary<string, object>
            {
                { "CPU", "Intel i7" },
                { "RAM", "16GB" },
                { "Storage", "512GB SSD" },
                { "Weight", 1.8 }
            }
        };
        
        // Newtonsoft.Json序列化设置
        var settings = new JsonSerializerSettings
        {
            Formatting = Formatting.Indented,
            DateFormatString = "yyyy-MM-dd HH:mm:ss",
            NullValueHandling = NullValueHandling.Ignore
        };
        
        string json = JsonConvert.SerializeObject(product, settings);
        Console.WriteLine($"Newtonsoft.Json序列化:\n{json}");
        
        // 反序列化
        Product deserializedProduct = JsonConvert.DeserializeObject<Product>(json, settings);
        Console.WriteLine($"\n反序列化结果:");
        Console.WriteLine($"产品: {deserializedProduct.Name}");
        Console.WriteLine($"价格: ¥{deserializedProduct.Price}");
        Console.WriteLine($"规格:");
        foreach (var spec in deserializedProduct.Specifications)
        {
            Console.WriteLine($"  {spec.Key}: {spec.Value}");
        }
    }
    
    private static void ComplexObjectSerialization()
    {
        // 创建复杂对象结构
        var company = new Company
        {
            Id = 1,
            Name = "科技有限公司",
            Address = new Address
            {
                Street = "中关村大街1号",
                City = "北京",
                Country = "中国",
                PostalCode = "100000"
            },
            Employees = new List<Employee>
            {
                new Employee
                {
                    Id = 1,
                    Name = "张三",
                    Position = "软件工程师",
                    Salary = 15000,
                    Department = new Department { Id = 1, Name = "技术部" }
                },
                new Employee
                {
                    Id = 2,
                    Name = "李四",
                    Position = "产品经理",
                    Salary = 18000,
                    Department = new Department { Id = 2, Name = "产品部" }
                }
            },
            Founded = new DateTime(2010, 3, 15)
        };
        
        // 序列化复杂对象
        var options = new JsonSerializerOptions
        {
            WriteIndented = true,
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
        };
        
        string json = JsonSerializer.Serialize(company, options);
        Console.WriteLine($"复杂对象序列化:\n{json}");
        
        // 反序列化
        Company deserializedCompany = JsonSerializer.Deserialize<Company>(json, options);
        Console.WriteLine($"\n反序列化验证:");
        Console.WriteLine($"公司: {deserializedCompany.Name}");
        Console.WriteLine($"地址: {deserializedCompany.Address.City}");
        Console.WriteLine($"员工数量: {deserializedCompany.Employees.Count}");
        
        foreach (var emp in deserializedCompany.Employees)
        {
            Console.WriteLine($"  {emp.Name} - {emp.Position} - {emp.Department.Name}");
        }
    }
    
    private static void CustomJsonSerialization()
    {
        var customObject = new CustomSerializationObject
        {
            Id = 1,
            PublicData = "公开数据",
            SensitiveData = "敏感数据",
            CreatedAt = DateTime.Now,
            Version = new Version(1, 2, 3)
        };
        
        // 使用自定义转换器
        var options = new JsonSerializerOptions
        {
            WriteIndented = true,
            Converters = { new VersionJsonConverter() }
        };
        
        string json = JsonSerializer.Serialize(customObject, options);
        Console.WriteLine($"自定义序列化:\n{json}");
        
        // 反序列化
        var deserializedObject = JsonSerializer.Deserialize<CustomSerializationObject>(json, options);
        Console.WriteLine($"\n反序列化结果:");
        Console.WriteLine($"ID: {deserializedObject.Id}");
        Console.WriteLine($"公开数据: {deserializedObject.PublicData}");
        Console.WriteLine($"敏感数据: {deserializedObject.SensitiveData ?? "[已忽略]"}")
        Console.WriteLine($"版本: {deserializedObject.Version}");
    }
}

// 数据模型类
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public string Email { get; set; }
    public DateTime BirthDate { get; set; }
    public bool IsActive { get; set; }
    public string[] Tags { get; set; }
}

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public string Category { get; set; }
    public bool InStock { get; set; }
    public DateTime CreatedAt { get; set; }
    public Dictionary<string, object> Specifications { get; set; }
}

public class Company
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }
    public List<Employee> Employees { get; set; }
    public DateTime Founded { get; set; }
}

public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
    public string PostalCode { get; set; }
}

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Position { get; set; }
    public decimal Salary { get; set; }
    public Department Department { get; set; }
}

public class Department
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class CustomSerializationObject
{
    public int Id { get; set; }
    public string PublicData { get; set; }
    
    [JsonIgnore]
    public string SensitiveData { get; set; }
    
    [JsonPropertyName("created_timestamp")]
    public DateTime CreatedAt { get; set; }
    
    public Version Version { get; set; }
}

// 自定义JSON转换器
public class VersionJsonConverter : JsonConverter<Version>
{
    public override Version Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        string versionString = reader.GetString();
        return Version.Parse(versionString);
    }
    
    public override void Write(Utf8JsonWriter writer, Version value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString());
    }
}

4.2 XML序列化

using System.Xml;
using System.Xml.Serialization;

public class XmlSerializationDemo
{
    public static void DemonstrateXmlSerialization()
    {
        Console.WriteLine("\n=== XML序列化演示 ===");
        
        Console.WriteLine("\n--- 基本XML序列化 ---");
        BasicXmlSerialization();
        
        Console.WriteLine("\n--- 复杂XML序列化 ---");
        ComplexXmlSerialization();
        
        Console.WriteLine("\n--- 自定义XML序列化 ---");
        CustomXmlSerialization();
    }
    
    private static void BasicXmlSerialization()
    {
        var book = new Book
        {
            Id = 1,
            Title = "C#编程指南",
            Author = "张三",
            Price = 89.99m,
            PublishDate = new DateTime(2023, 6, 15),
            ISBN = "978-7-111-12345-6",
            InStock = true
        };
        
        string xmlFile = Path.Combine(Path.GetTempPath(), "book.xml");
        
        try
        {
            // XML序列化
            var serializer = new XmlSerializer(typeof(Book));
            
            using (var writer = new StreamWriter(xmlFile))
            {
                serializer.Serialize(writer, book);
            }
            
            Console.WriteLine($"XML已保存到: {xmlFile}");
            
            // 读取并显示XML内容
            string xmlContent = File.ReadAllText(xmlFile);
            Console.WriteLine($"\nXML内容:\n{xmlContent}");
            
            // XML反序列化
            using (var reader = new StreamReader(xmlFile))
            {
                Book deserializedBook = (Book)serializer.Deserialize(reader);
                
                Console.WriteLine($"\n反序列化结果:");
                Console.WriteLine($"书名: {deserializedBook.Title}");
                Console.WriteLine($"作者: {deserializedBook.Author}");
                Console.WriteLine($"价格: ¥{deserializedBook.Price}");
                Console.WriteLine($"出版日期: {deserializedBook.PublishDate:yyyy-MM-dd}");
                Console.WriteLine($"ISBN: {deserializedBook.ISBN}");
                Console.WriteLine($"库存: {deserializedBook.InStock}");
            }
        }
        finally
        {
            if (File.Exists(xmlFile))
            {
                File.Delete(xmlFile);
            }
        }
    }
    
    private static void ComplexXmlSerialization()
    {
        var library = new Library
        {
            Name = "市图书馆",
            Address = "文化路123号",
            Books = new List<BookInfo>
            {
                new BookInfo
                {
                    Id = 1,
                    Title = "C#高级编程",
                    Authors = new[] { "张三", "李四" },
                    Categories = new[] { "编程", "技术", "计算机" },
                    Details = new BookDetails
                    {
                        Pages = 500,
                        Language = "中文",
                        Publisher = "机械工业出版社"
                    }
                },
                new BookInfo
                {
                    Id = 2,
                    Title = "数据结构与算法",
                    Authors = new[] { "王五" },
                    Categories = new[] { "算法", "数据结构" },
                    Details = new BookDetails
                    {
                        Pages = 350,
                        Language = "中文",
                        Publisher = "清华大学出版社"
                    }
                }
            }
        };
        
        string xmlFile = Path.Combine(Path.GetTempPath(), "library.xml");
        
        try
        {
            // 序列化复杂对象
            var serializer = new XmlSerializer(typeof(Library));
            
            var settings = new XmlWriterSettings
            {
                Indent = true,
                IndentChars = "  ",
                Encoding = Encoding.UTF8
            };
            
            using (var writer = XmlWriter.Create(xmlFile, settings))
            {
                serializer.Serialize(writer, library);
            }
            
            Console.WriteLine($"复杂XML已保存到: {xmlFile}");
            
            // 显示XML内容
            string xmlContent = File.ReadAllText(xmlFile, Encoding.UTF8);
            Console.WriteLine($"\nXML内容:\n{xmlContent}");
            
            // 反序列化
            using (var reader = XmlReader.Create(xmlFile))
            {
                Library deserializedLibrary = (Library)serializer.Deserialize(reader);
                
                Console.WriteLine($"\n反序列化结果:");
                Console.WriteLine($"图书馆: {deserializedLibrary.Name}");
                Console.WriteLine($"地址: {deserializedLibrary.Address}");
                Console.WriteLine($"图书数量: {deserializedLibrary.Books.Count}");
                
                foreach (var book in deserializedLibrary.Books)
                {
                    Console.WriteLine($"\n  书名: {book.Title}");
                    Console.WriteLine($"  作者: {string.Join(", ", book.Authors)}");
                    Console.WriteLine($"  分类: {string.Join(", ", book.Categories)}");
                    Console.WriteLine($"  页数: {book.Details.Pages}");
                    Console.WriteLine($"  出版社: {book.Details.Publisher}");
                }
            }
        }
        finally
        {
            if (File.Exists(xmlFile))
            {
                File.Delete(xmlFile);
            }
        }
    }
    
    private static void CustomXmlSerialization()
    {
        var config = new ApplicationConfig
        {
            AppName = "MyApplication",
            Version = "1.0.0",
            DatabaseSettings = new DatabaseConfig
            {
                ConnectionString = "Server=localhost;Database=MyDB",
                Timeout = 30,
                EnableLogging = true
            },
            Features = new List<FeatureConfig>
            {
                new FeatureConfig { Name = "Authentication", Enabled = true, Settings = new Dictionary<string, string> { { "Provider", "OAuth" } } },
                new FeatureConfig { Name = "Caching", Enabled = false, Settings = new Dictionary<string, string> { { "Type", "Redis" } } }
            }
        };
        
        string xmlFile = Path.Combine(Path.GetTempPath(), "config.xml");
        
        try
        {
            // 自定义XML序列化
            var serializer = new XmlSerializer(typeof(ApplicationConfig));
            
            var namespaces = new XmlSerializerNamespaces();
            namespaces.Add("app", "http://mycompany.com/application");
            
            var settings = new XmlWriterSettings
            {
                Indent = true,
                IndentChars = "  ",
                Encoding = Encoding.UTF8
            };
            
            using (var writer = XmlWriter.Create(xmlFile, settings))
            {
                serializer.Serialize(writer, config, namespaces);
            }
            
            Console.WriteLine($"自定义XML已保存到: {xmlFile}");
            
            // 显示XML内容
            string xmlContent = File.ReadAllText(xmlFile, Encoding.UTF8);
            Console.WriteLine($"\nXML内容:\n{xmlContent}");
            
            // 反序列化
            using (var reader = XmlReader.Create(xmlFile))
            {
                ApplicationConfig deserializedConfig = (ApplicationConfig)serializer.Deserialize(reader);
                
                Console.WriteLine($"\n反序列化结果:");
                Console.WriteLine($"应用名称: {deserializedConfig.AppName}");
                Console.WriteLine($"版本: {deserializedConfig.Version}");
                Console.WriteLine($"数据库连接: {deserializedConfig.DatabaseSettings.ConnectionString}");
                Console.WriteLine($"功能配置:");
                
                foreach (var feature in deserializedConfig.Features)
                {
                    Console.WriteLine($"  {feature.Name}: {(feature.Enabled ? "启用" : "禁用")}");
                    foreach (var setting in feature.Settings)
                    {
                        Console.WriteLine($"    {setting.Key} = {setting.Value}");
                    }
                }
            }
        }
        finally
        {
            if (File.Exists(xmlFile))
            {
                File.Delete(xmlFile);
            }
        }
    }
}

// XML序列化数据模型
[XmlRoot("Book")]
public class Book
{
    [XmlAttribute("id")]
    public int Id { get; set; }
    
    [XmlElement("Title")]
    public string Title { get; set; }
    
    [XmlElement("Author")]
    public string Author { get; set; }
    
    [XmlElement("Price")]
    public decimal Price { get; set; }
    
    [XmlElement("PublishDate")]
    public DateTime PublishDate { get; set; }
    
    [XmlElement("ISBN")]
    public string ISBN { get; set; }
    
    [XmlElement("InStock")]
    public bool InStock { get; set; }
}

[XmlRoot("Library")]
public class Library
{
    [XmlAttribute("name")]
    public string Name { get; set; }
    
    [XmlElement("Address")]
    public string Address { get; set; }
    
    [XmlArray("Books")]
    [XmlArrayItem("Book")]
    public List<BookInfo> Books { get; set; }
}

public class BookInfo
{
    [XmlAttribute("id")]
    public int Id { get; set; }
    
    [XmlElement("Title")]
    public string Title { get; set; }
    
    [XmlArray("Authors")]
    [XmlArrayItem("Author")]
    public string[] Authors { get; set; }
    
    [XmlArray("Categories")]
    [XmlArrayItem("Category")]
    public string[] Categories { get; set; }
    
    [XmlElement("Details")]
    public BookDetails Details { get; set; }
}

public class BookDetails
{
    [XmlElement("Pages")]
    public int Pages { get; set; }
    
    [XmlElement("Language")]
    public string Language { get; set; }
    
    [XmlElement("Publisher")]
    public string Publisher { get; set; }
}

[XmlRoot("Configuration", Namespace = "http://mycompany.com/application")]
public class ApplicationConfig
{
    [XmlAttribute("name")]
    public string AppName { get; set; }
    
    [XmlAttribute("version")]
    public string Version { get; set; }
    
    [XmlElement("Database")]
    public DatabaseConfig DatabaseSettings { get; set; }
    
    [XmlArray("Features")]
    [XmlArrayItem("Feature")]
    public List<FeatureConfig> Features { get; set; }
}

public class DatabaseConfig
{
    [XmlElement("ConnectionString")]
    public string ConnectionString { get; set; }
    
    [XmlElement("Timeout")]
    public int Timeout { get; set; }
    
    [XmlElement("EnableLogging")]
    public bool EnableLogging { get; set; }
}

public class FeatureConfig
{
    [XmlAttribute("name")]
    public string Name { get; set; }
    
    [XmlAttribute("enabled")]
    public bool Enabled { get; set; }
    
    [XmlIgnore]
    public Dictionary<string, string> Settings { get; set; } = new Dictionary<string, string>();
    
    [XmlArray("Settings")]
    [XmlArrayItem("Setting")]
    public SettingItem[] SettingsArray
    {
        get
        {
            return Settings?.Select(kvp => new SettingItem { Key = kvp.Key, Value = kvp.Value }).ToArray();
        }
        set
        {
            Settings = value?.ToDictionary(item => item.Key, item => item.Value) ?? new Dictionary<string, string>();
        }
    }
}

public class SettingItem
{
    [XmlAttribute("key")]
    public string Key { get; set; }
    
    [XmlAttribute("value")]
    public string Value { get; set; }
}

二进制序列化

1. BinaryFormatter(已过时)

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

[Serializable]
public class LegacyData
{
    public string Name { get; set; }
    public int Value { get; set; }
    public DateTime CreatedAt { get; set; }
}

public class LegacyBinarySerialization
{
    // 注意:BinaryFormatter在.NET 5+中已被标记为过时
    // 仅用于演示,实际项目中不推荐使用
    public static void SerializeToFile(object obj, string filePath)
    {
        using var stream = new FileStream(filePath, FileMode.Create);
        var formatter = new BinaryFormatter();
        formatter.Serialize(stream, obj);
    }
    
    public static T DeserializeFromFile<T>(string filePath)
    {
        using var stream = new FileStream(filePath, FileMode.Open);
        var formatter = new BinaryFormatter();
        return (T)formatter.Deserialize(stream);
    }
}

2. 现代二进制序列化方案

using System;
using System.IO;
using System.Text.Json;
using MessagePack;

// MessagePack序列化(推荐的二进制序列化方案)
[MessagePackObject]
public class ModernData
{
    [Key(0)]
    public string Name { get; set; }
    
    [Key(1)]
    public int Value { get; set; }
    
    [Key(2)]
    public DateTime CreatedAt { get; set; }
    
    [Key(3)]
    public List<string> Tags { get; set; } = new();
}

public class ModernBinarySerialization
{
    // MessagePack序列化
    public static byte[] SerializeMessagePack<T>(T obj)
    {
        return MessagePackSerializer.Serialize(obj);
    }
    
    public static T DeserializeMessagePack<T>(byte[] data)
    {
        return MessagePackSerializer.Deserialize<T>(data);
    }
    
    // 使用System.Text.Json的UTF8字节序列化
    public static byte[] SerializeJsonUtf8<T>(T obj)
    {
        return JsonSerializer.SerializeToUtf8Bytes(obj);
    }
    
    public static T DeserializeJsonUtf8<T>(byte[] data)
    {
        return JsonSerializer.Deserialize<T>(data);
    }
    
    // 自定义二进制协议
    public static byte[] SerializeCustom(ModernData data)
    {
        using var stream = new MemoryStream();
        using var writer = new BinaryWriter(stream);
        
        // 写入版本号
        writer.Write((byte)1);
        
        // 写入字符串
        writer.Write(data.Name ?? string.Empty);
        
        // 写入整数
        writer.Write(data.Value);
        
        // 写入日期时间
        writer.Write(data.CreatedAt.ToBinary());
        
        // 写入标签列表
        writer.Write(data.Tags.Count);
        foreach (var tag in data.Tags)
        {
            writer.Write(tag);
        }
        
        return stream.ToArray();
    }
    
    public static ModernData DeserializeCustom(byte[] data)
    {
        using var stream = new MemoryStream(data);
        using var reader = new BinaryReader(stream);
        
        // 读取版本号
        var version = reader.ReadByte();
        if (version != 1)
            throw new InvalidDataException($"Unsupported version: {version}");
        
        var result = new ModernData
        {
            Name = reader.ReadString(),
            Value = reader.ReadInt32(),
            CreatedAt = DateTime.FromBinary(reader.ReadInt64())
        };
        
        // 读取标签列表
        var tagCount = reader.ReadInt32();
        for (int i = 0; i < tagCount; i++)
        {
            result.Tags.Add(reader.ReadString());
        }
        
        return result;
    }
}

高级序列化技术

1. 自定义序列化控制

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

public class AdvancedSerializationControl
{
    [JsonPropertyName("full_name")]
    public string Name { get; set; }
    
    [JsonIgnore]
    public string Password { get; set; }
    
    [JsonPropertyName("birth_date")]
    [JsonConverter(typeof(DateOnlyJsonConverter))]
    public DateOnly BirthDate { get; set; }
    
    [JsonPropertyName("metadata")]
    [JsonConverter(typeof(DictionaryStringObjectJsonConverter))]
    public Dictionary<string, object> Metadata { get; set; } = new();
    
    // 条件序列化
    public bool ShouldSerializePassword() => false;
    
    // 序列化回调
    [JsonExtensionData]
    public Dictionary<string, JsonElement> ExtensionData { get; set; }
}

// 自定义日期转换器
public class DateOnlyJsonConverter : JsonConverter<DateOnly>
{
    public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return DateOnly.ParseExact(reader.GetString(), "yyyy-MM-dd");
    }
    
    public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString("yyyy-MM-dd"));
    }
}

// 自定义字典转换器
public class DictionaryStringObjectJsonConverter : JsonConverter<Dictionary<string, object>>
{
    public override Dictionary<string, object> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var dictionary = new Dictionary<string, object>();
        
        if (reader.TokenType != JsonTokenType.StartObject)
            throw new JsonException();
        
        while (reader.Read())
        {
            if (reader.TokenType == JsonTokenType.EndObject)
                return dictionary;
            
            if (reader.TokenType != JsonTokenType.PropertyName)
                throw new JsonException();
            
            string propertyName = reader.GetString();
            reader.Read();
            
            dictionary[propertyName] = ReadValue(ref reader);
        }
        
        throw new JsonException();
    }
    
    private object ReadValue(ref Utf8JsonReader reader)
    {
        return reader.TokenType switch
        {
            JsonTokenType.String => reader.GetString(),
            JsonTokenType.Number => reader.TryGetInt32(out int intValue) ? intValue : reader.GetDouble(),
            JsonTokenType.True => true,
            JsonTokenType.False => false,
            JsonTokenType.Null => null,
            _ => throw new JsonException($"Unsupported token type: {reader.TokenType}")
        };
    }
    
    public override void Write(Utf8JsonWriter writer, Dictionary<string, object> value, JsonSerializerOptions options)
    {
        writer.WriteStartObject();
        
        foreach (var kvp in value)
        {
            writer.WritePropertyName(kvp.Key);
            WriteValue(writer, kvp.Value);
        }
        
        writer.WriteEndObject();
    }
    
    private void WriteValue(Utf8JsonWriter writer, object value)
    {
        switch (value)
        {
            case null:
                writer.WriteNullValue();
                break;
            case string s:
                writer.WriteStringValue(s);
                break;
            case int i:
                writer.WriteNumberValue(i);
                break;
            case double d:
                writer.WriteNumberValue(d);
                break;
            case bool b:
                writer.WriteBooleanValue(b);
                break;
            default:
                writer.WriteStringValue(value.ToString());
                break;
        }
    }
}

2. 流式序列化

using System;
using System.IO;
using System.Text.Json;
using System.Collections.Generic;

public class StreamingSerialization
{
    // 流式写入大量数据
    public static async Task WriteJsonStreamAsync<T>(IEnumerable<T> items, Stream stream)
    {
        using var writer = new Utf8JsonWriter(stream);
        
        writer.WriteStartArray();
        
        foreach (var item in items)
        {
            JsonSerializer.Serialize(writer, item);
            await writer.FlushAsync();
        }
        
        writer.WriteEndArray();
        await writer.FlushAsync();
    }
    
    // 流式读取大量数据
    public static async IAsyncEnumerable<T> ReadJsonStreamAsync<T>(Stream stream)
    {
        using var document = await JsonDocument.ParseAsync(stream);
        
        if (document.RootElement.ValueKind != JsonValueKind.Array)
            throw new JsonException("Expected JSON array");
        
        foreach (var element in document.RootElement.EnumerateArray())
        {
            yield return JsonSerializer.Deserialize<T>(element.GetRawText());
        }
    }
    
    // 分块处理大文件
    public static async Task ProcessLargeJsonFileAsync<T>(string filePath, Func<T, Task> processor)
    {
        using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
        
        await foreach (var item in ReadJsonStreamAsync<T>(fileStream))
        {
            await processor(item);
        }
    }
}

// 使用示例
public class StreamingDemo
{
    public static async Task DemoStreamingSerialization()
    {
        var largeDataSet = GenerateLargeDataSet(100000);
        
        // 写入大文件
        using (var fileStream = new FileStream("large_data.json", FileMode.Create))
        {
            await StreamingSerialization.WriteJsonStreamAsync(largeDataSet, fileStream);
        }
        
        // 流式处理大文件
        await StreamingSerialization.ProcessLargeJsonFileAsync<DataItem>(
            "large_data.json",
            async item =>
            {
                // 处理每个数据项
                Console.WriteLine($"Processing: {item.Id}");
                await Task.Delay(1); // 模拟处理时间
            });
    }
    
    private static IEnumerable<DataItem> GenerateLargeDataSet(int count)
    {
        for (int i = 0; i < count; i++)
        {
            yield return new DataItem
            {
                Id = i,
                Name = $"Item_{i}",
                Value = Random.Shared.NextDouble() * 1000,
                CreatedAt = DateTime.Now.AddDays(-Random.Shared.Next(365))
            };
        }
    }
}

public class DataItem
{
    public int Id { get; set; }
    public string Name { get; set; }
    public double Value { get; set; }
    public DateTime CreatedAt { get; set; }
}

性能优化和最佳实践

1. 序列化性能优化

using System;
using System.Buffers;
using System.IO;
using System.Text.Json;
using System.Diagnostics;

public class SerializationPerformance
{
    // 使用ArrayPool减少内存分配
    public static byte[] SerializeWithArrayPool<T>(T obj)
    {
        var bufferWriter = new ArrayBufferWriter<byte>();
        using var writer = new Utf8JsonWriter(bufferWriter);
        
        JsonSerializer.Serialize(writer, obj);
        
        return bufferWriter.WrittenSpan.ToArray();
    }
    
    // 预编译序列化器
    private static readonly JsonSerializerOptions _optimizedOptions = new()
    {
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
        WriteIndented = false
    };
    
    public static string SerializeOptimized<T>(T obj)
    {
        return JsonSerializer.Serialize(obj, _optimizedOptions);
    }
    
    // 性能测试
    public static void BenchmarkSerialization<T>(T testObject, int iterations = 10000)
    {
        var stopwatch = Stopwatch.StartNew();
        
        // 测试标准序列化
        stopwatch.Restart();
        for (int i = 0; i < iterations; i++)
        {
            JsonSerializer.Serialize(testObject);
        }
        stopwatch.Stop();
        Console.WriteLine($"Standard serialization: {stopwatch.ElapsedMilliseconds}ms");
        
        // 测试优化序列化
        stopwatch.Restart();
        for (int i = 0; i < iterations; i++)
        {
            SerializeOptimized(testObject);
        }
        stopwatch.Stop();
        Console.WriteLine($"Optimized serialization: {stopwatch.ElapsedMilliseconds}ms");
        
        // 测试ArrayPool序列化
        stopwatch.Restart();
        for (int i = 0; i < iterations; i++)
        {
            SerializeWithArrayPool(testObject);
        }
        stopwatch.Stop();
        Console.WriteLine($"ArrayPool serialization: {stopwatch.ElapsedMilliseconds}ms");
    }
}

2. 文件操作最佳实践

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

public class FileOperationBestPractices
{
    // 安全的文件写入(原子操作)
    public static async Task SafeWriteAllTextAsync(string filePath, string content)
    {
        var tempPath = filePath + ".tmp";
        
        try
        {
            await File.WriteAllTextAsync(tempPath, content);
            
            // 原子性替换
            if (File.Exists(filePath))
            {
                File.Replace(tempPath, filePath, filePath + ".bak");
            }
            else
            {
                File.Move(tempPath, filePath);
            }
        }
        catch
        {
            // 清理临时文件
            if (File.Exists(tempPath))
            {
                File.Delete(tempPath);
            }
            throw;
        }
    }
    
    // 带重试的文件操作
    public static async Task<T> RetryFileOperation<T>(Func<Task<T>> operation, int maxRetries = 3)
    {
        for (int i = 0; i < maxRetries; i++)
        {
            try
            {
                return await operation();
            }
            catch (IOException) when (i < maxRetries - 1)
            {
                await Task.Delay(TimeSpan.FromMilliseconds(100 * Math.Pow(2, i)));
            }
        }
        
        return await operation(); // 最后一次尝试,不捕获异常
    }
    
    // 文件完整性验证
    public static async Task<bool> VerifyFileIntegrityAsync(string filePath, string expectedHash)
    {
        using var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
        using var sha256 = SHA256.Create();
        
        var hash = await sha256.ComputeHashAsync(stream);
        var hashString = Convert.ToHexString(hash);
        
        return string.Equals(hashString, expectedHash, StringComparison.OrdinalIgnoreCase);
    }
    
    // 大文件分块处理
    public static async Task ProcessLargeFileAsync(string filePath, Func<ReadOnlyMemory<byte>, Task> processor, int bufferSize = 8192)
    {
        using var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
        var buffer = new byte[bufferSize];
        
        int bytesRead;
        while ((bytesRead = await stream.ReadAsync(buffer)) > 0)
        {
            await processor(buffer.AsMemory(0, bytesRead));
        }
    }
    
    // 并发安全的文件访问
    private static readonly SemaphoreSlim _fileSemaphore = new(1, 1);
    
    public static async Task<string> SafeReadAllTextAsync(string filePath)
    {
        await _fileSemaphore.WaitAsync();
        try
        {
            return await File.ReadAllTextAsync(filePath);
        }
        finally
        {
            _fileSemaphore.Release();
        }
    }
}