怪奇物语

怪奇物语

首页 新随笔 联系 管理

new code2md

Code2md\Code2md.csproj


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

Code2md\Code2mdTask.cs


public class Code2mdTask
{
    public string CodePath { get; set; }
    public string MarkdownTitle { get; set; }
    public string DstCodePath { get; set; } 
    public string DstMdCodePath { get; set; } 
}


Code2md\Program.cs


using System.Collections.Concurrent;
using System.Text.RegularExpressions;
using System.Xml;

class Program
{
    private static string SourceDirectory = string.Empty;
    private static string DirectorySuffix = string.Empty;

    private static readonly DateTime Now = DateTime.Now;

    // @"D:\inetpub\wwwroot\Mes\szaddon\szpH060\HSLPAD";
    // @"D:\inetpub\wwwroot\Mes\szaddon\szpH060\Picture";
    // @"D:\inetpub\wwwroot\Mes\szaddon\szpH060\OQC_reports";
    private static readonly List<string> ExcludedEqualDirectories = new List<string> { ".github", ".vscode", "bin", "obj" };
    private static readonly string DestinationDirectory = @"Z:\inetpub\wwwroot\Mes\szaddon\szpH060\HSLPAD";
    private static readonly ConcurrentQueue<Code2mdTask> FileMoveQueue = new ConcurrentQueue<Code2mdTask>();
    private static readonly CancellationTokenSource CancellationTokenSource = new CancellationTokenSource();
    private static readonly ManualResetEventSlim AllFilesProcessed = new ManualResetEventSlim(false);
    private static int _totalFiles = 0;
    private static int _completedFiles = 0;
    private static readonly object _lockObject = new object();

    static void Main(string[] args)
    {
        if (args.Length == 0)
        {
            System.Console.WriteLine("请传入文件夹路径");
            return;
        }
        SourceDirectory = args[0];
        try
        {
            // 检查源目录是否存在
            if (!Directory.Exists(SourceDirectory))
            {
                Console.WriteLine($"错误: 源目录 {SourceDirectory} 不存在。");
                return;
            }
            // 扫描源目录并准备移动任务
            Console.WriteLine("正在扫描文件...");
            System.Console.WriteLine("输入文件夹后缀:");
            DirectorySuffix = System.Console.ReadLine() ?? string.Empty;
            string[] directories = Directory.GetDirectories(SourceDirectory);
            var getFileTasks = new List<Task>();

            foreach (string dirPath in directories)
            {
                bool flowControl = FilterFolder(dirPath);
                if (!flowControl)
                {
                    continue;
                }
                getFileTasks.Add(Task.Run(() => ScanDirectory(dirPath)));
            }
            getFileTasks.Add(Task.Run(() => ScanDirectory(SourceDirectory)));

            Task.WaitAll(getFileTasks);
            Console.WriteLine($"已扫描完成,共找到 {_totalFiles} 个文件。");
            if (_totalFiles == 0)
            {
                Console.WriteLine("没有文件需要Code2md转换。");
                return;
            }
            // 启动进度显示线程
            var progressThread = new Thread(ShowProgress);
            progressThread.IsBackground = true;
            progressThread.Start();

            // 启动多个工作线程
            const int maxThreads = 8;
            var tasks = new Task[maxThreads];
            for (int i = 0; i < maxThreads; i++)
            {
                tasks[i] = Task.Run(() => CodeBackup(CancellationTokenSource.Token));
            }
            // 等待所有任务完成
            Task.WaitAll(tasks);
            AllFilesProcessed.Wait();

            Console.WriteLine("\n所有文件移动完成!");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"\n发生致命错误: {ex.Message}");
        }
        finally
        {
            CancellationTokenSource.Cancel();
            AllFilesProcessed.Dispose();
        }
        Console.WriteLine("============备份完成============");
    }

    private static bool FilterFolder(string dirPath)
    {
        var dirName = Path.GetFileNameWithoutExtension(dirPath);
        if (ExcludedEqualDirectories.Exists(d => d.Equals(dirName)))
        {
            return false;
        }
        return true;
    }

    private static void ScanDirectory(string sourcePath)
    {
        try
        {
            GetFiles(sourcePath);
            string[] directories = Directory.GetDirectories(sourcePath);
            foreach (string directory in directories)
            {
                bool flowControl = FilterFolder(directory);
                if (!flowControl)
                {
                    continue;
                }
                ScanDirectory(directory);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"扫描目录时出错 ({sourcePath}): {ex.Message}");
        }
    }

    private static void GetFiles(string sourcePath)
    {
        var regex = new Regex(@"\.(cs|js|html|css|py|java|cpp|h|xaml|ts|csproj|bat|sln|json|go)$", RegexOptions.IgnoreCase);
        var files = Directory.EnumerateFiles(sourcePath, "*", SearchOption.TopDirectoryOnly).Where(file => regex.IsMatch(file));
        foreach (string filePath in files)
        {
            string relativePath = Path.GetRelativePath(SourceDirectory, filePath);
            string grandFatherFolderPath = Path.GetDirectoryName(SourceDirectory)!;
            string brotherFolderPath = Path.GetFileName(SourceDirectory) + $"_{Now:yyyyMMdd_HHmmss}_{DirectorySuffix}";
            string dstCodePath = Path.Combine(grandFatherFolderPath, brotherFolderPath, relativePath);
            string dstMdCodePath = Path.Combine(SourceDirectory, "zz_pro", brotherFolderPath, relativePath + ".md");
            FileMoveQueue.Enqueue(
                new Code2mdTask
                {
                    CodePath = filePath,
                    MarkdownTitle = relativePath,
                    DstCodePath = dstCodePath,
                    DstMdCodePath = dstMdCodePath
                }
            );
            Interlocked.Increment(ref _totalFiles);
        }
    }

    private static void CodeBackup(CancellationToken cancellationToken)
    {
        while (!cancellationToken.IsCancellationRequested)
        {
            if (FileMoveQueue.TryDequeue(out Code2mdTask? task))
            {
                if (task != null && string.IsNullOrEmpty(task.CodePath))
                {
                    continue; // 跳过空任务
                }
                System.Console.WriteLine($"正在处理文件: {task.CodePath} -> {task.MarkdownTitle}");
                try
                {
                    Code2md(task);
                    Interlocked.Increment(ref _completedFiles);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"复制文件时出错 ({task.CodePath} -> {task.MarkdownTitle}): {ex.Message}");
                }
            }
            else if (_completedFiles == _totalFiles)
            {
                AllFilesProcessed.Set();
                break;
            }
            else
            {
                // 队列暂时为空,等待片刻
                Thread.Sleep(100);
            }
        }
    }

    private static void Code2md(Code2mdTask code2mdTask, int maxRetries = 3)
    {
        int retries = 0;
        while (true)
        {
            try
            {
                string codePath = code2mdTask.CodePath;
                string markdownTitle = code2mdTask.MarkdownTitle;
                string dstCodePath = code2mdTask.DstCodePath;
                string dstMdCodePath = code2mdTask.DstMdCodePath;

                if (!File.Exists(dstCodePath))
                {
                    if (!Directory.Exists(Path.GetDirectoryName(dstCodePath)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(dstCodePath)!);
                    }
                    File.Copy(codePath, dstCodePath, false);
                }

                if (!File.Exists(dstMdCodePath))
                {
                    if (!Directory.Exists(Path.GetDirectoryName(dstMdCodePath)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(dstMdCodePath)!);
                    }
                    File.Copy(codePath, dstMdCodePath, false);
                }
                // 验证文件是否成功移动
                if (!File.Exists(dstCodePath) || !File.Exists(dstMdCodePath))
                {
                    throw new IOException("文件复制后不存在于目标位置");
                }
                break;
            }
            catch (Exception ex)
            {
                retries++;
                if (retries > maxRetries)
                {
                    // Console.WriteLine($"文件移动失败 ({codePath} -> {markdownTitle}): {ex.Message}");
                    throw;
                }
                // 等待一段时间后重试
                Thread.Sleep(500 * retries);
            }
        }
    }

    private static void ShowProgress()
    {
        while (!AllFilesProcessed.IsSet)
        {
            lock (_lockObject)
            {
                Console.CursorLeft = 0;
                Console.Write($"进度: {_completedFiles}/{_totalFiles} 文件 ({_completedFiles * 100.0 / Math.Max(1, _totalFiles):F2}%)");
            }
            Thread.Sleep(100);
        }
    }
}



posted on 2025-07-10 08:00  超级无敌美少男战士  阅读(9)  评论(0)    收藏  举报