You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#能否同时读写同一文本文件?及批量处理SQL文件GRANT语句方案

嘿,我来帮你解决这两个问题:

问题1:C#中能否同时对同一个文本文件进行读取和写入操作?

答案是可以,但需要注意文件访问权限和锁机制——直接用默认方式打开同一个文件进行读写,大概率会因为文件独占锁抛出异常。这里推荐两种稳妥的实现方式:

方式1:通过FileStream设置共享权限

你可以用File.Open创建流时,指定FileAccess.ReadWrite和合适的FileShare参数,允许同时读写操作,但要手动控制指针位置,避免读写冲突:

using (var stream = File.Open("example.txt", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
    // 读取全部内容
    var reader = new StreamReader(stream);
    string content = reader.ReadToEnd();
    
    // 将指针移回文件开头(准备覆盖写入)
    stream.Seek(0, SeekOrigin.Begin);
    
    // 写入修改后的内容
    var writer = new StreamWriter(stream);
    writer.Write(content.Replace("old_text", "new_text"));
    
    // 截断原文件中多余的内容(如果新内容比原内容短)
    stream.SetLength(stream.Position);
}

方式2:先读入内存再写入(更安全推荐)

对于大多数场景(比如你的SQL文件处理),更推荐先把文件内容全部读入内存,修改后再覆盖写入文件。这种方式避免了并发读写的冲突,代码也更简洁:

// 读取文件到内存
string content = File.ReadAllText("target.sql");

// 修改内容(比如移除GRANT语句)
string cleanedContent = RemoveGrantStatements(content);

// 覆盖写入原文件
File.WriteAllText("target.sql", cleanedContent);

问题2:批量移除SQL文件中的GRANT语句并单独保存

针对你1500+ SQL文件的处理需求,我们可以用C#结合正则表达式实现批量操作,核心思路和代码如下:

核心流程

  1. 遍历指定目录下的所有.sql文件
  2. 对每个文件:
    • 读取全部内容
    • 用正则匹配并提取所有GRANT语句(支持单行/跨行分布)
    • 移除原内容中的GRANT语句
    • 将清理后的内容写回原文件
    • 将提取的GRANT语句写入对应新文件(例如原文件名_Grants.sql)

关键正则表达式

因为GRANT语句可能跨行,我们需要启用Singleline模式让.匹配换行符,同时忽略SQL的大小写特性:

// 匹配GRANT语句:从GRANT开头到分号结束,支持跨行
var grantRegex = new Regex(@"\bGRANT\s+.+?;\s*", RegexOptions.IgnoreCase | RegexOptions.Singleline);

这个正则会匹配所有以GRANT开头、到第一个;结束的内容,包括中间包含换行的情况,同时兼容SQL不区分大小写的特性。

完整代码实现

using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Linq;

class SqlGrantBatchProcessor
{
    static void Main(string[] args)
    {
        // 替换为你的SQL文件存放目录
        string sqlRootDir = @"C:\Your_Sql_Files_Path";
        // 获取目录下所有.sql文件(如需处理子目录,把TopDirectoryOnly改成AllDirectories)
        var sqlFiles = Directory.EnumerateFiles(sqlRootDir, "*.sql", SearchOption.TopDirectoryOnly);

        // 初始化GRANT语句正则
        var grantRegex = new Regex(@"\bGRANT\s+.+?;\s*", RegexOptions.IgnoreCase | RegexOptions.Singleline);

        foreach (var filePath in sqlFiles)
        {
            try
            {
                // 读取文件内容(注意:如果你的文件是GBK等非UTF8编码,需指定Encoding,比如Encoding.GetEncoding("GB2312"))
                string originalContent = File.ReadAllText(filePath);

                // 提取所有GRANT语句
                var grantMatches = grantRegex.Matches(originalContent);
                string grantContent = string.Join(Environment.NewLine, 
                    grantMatches.Cast<Match>().Select(m => m.Value.Trim()));

                // 移除原内容中的GRANT语句
                string cleanedContent = grantRegex.Replace(originalContent, string.Empty).Trim();

                // 写回清理后的原文件
                File.WriteAllText(filePath, cleanedContent);

                // 生成GRANT文件路径并写入(仅当提取到内容时)
                if (!string.IsNullOrEmpty(grantContent))
                {
                    string grantFilePath = Path.Combine(
                        Path.GetDirectoryName(filePath), 
                        $"{Path.GetFileNameWithoutExtension(filePath)}_Grants.sql"
                    );
                    File.WriteAllText(grantFilePath, grantContent);
                    Console.WriteLine($"✅ 处理完成:{filePath} | 已提取GRANT到{grantFilePath}");
                }
                else
                {
                    Console.WriteLine($"ℹ️ 处理完成:{filePath} | 未找到GRANT语句");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"❌ 处理文件{filePath}出错:{ex.Message}");
            }
        }

        Console.WriteLine("\n所有文件处理完毕!");
        Console.ReadLine();
    }
}

注意事项

  • 编码兼容性:如果你的SQL文件不是UTF8编码,需要在File.ReadAllText和File.WriteAllText中指定对应编码(比如Encoding.ASCII或Encoding.GetEncoding("GBK"))。
  • 备份文件:处理前请务必备份所有SQL文件,避免意外导致数据丢失。
  • 正则微调:如果你的GRANT语句包含特殊格式(比如带引号的表名/用户名),当前正则已能兼容,若有特殊场景可再调整正则规则。

内容的提问来源于stack exchange,提问作者Richard Anderson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:43:49