StreamWriter C#格式化输出

StreamWriter C# formatting output

问题陈述

为了运行基因注释软件,我需要准备两种类型的文件,vcard文件和coverage tables,并且vcard要一一匹配覆盖率 table。由于我 运行ning 2k 个样本,因此很难确定哪个文件不是一对一匹配。我知道这两个文件都有唯一的标识符号,因此,如果两个文件夹都有具有相同唯一号的文件,我将其视为 "same" 文件


我制作了一个程序来比较两个文件夹并报告每个文件夹中的唯一条目。为此,我制作了两个列表,其中包含每个目录的唯一文件名。

我想将报告文件(制表符分隔的 .txt 文件)格式化为如下所示:

Unique in fdr1    Unique in fdr2
file x    file a
file y    file b
file z    file c

我发现这很难做到,因为我必须迭代两次(因为我有两个列表),但据我所知,没有办法返回到 StreamWriter 中的上一行。基本上,一旦我遍历第一个列表并填充第一列,我怎样才能用第二个列表填充第二列?

有人可以帮我解决这个问题吗?

谢谢

如果代码的设计必须改变(即一个列表而不是两个),请告诉我

应某些用户的要求,这就是我要做的(不是工作版本)

// Write report
        using (StreamWriter sw = new StreamWriter(dest_txt.Text + @"\" + "Report.txt"))
        {
            // Write headers
            sw.WriteLine("Unique Entries in Folder1" + "\t" + "Unique Entries in Folder2");

            // Write unique entries in fdr1
            foreach(string file in fdr1FileList)
            {
                sw.WriteLine(file + "\t");
            }

            // Write unique entries in fdr2
            foreach (string file in fdr2FileList)
            {
                sw.WriteLine(file + "\t");
            }
            sw.Dispose();
        }

根据我寻找独特条目的方法的要求,这是我的代码片段

        Dictionary<int, bool> fdr1Dict = new Dictionary<int, bool>();
        Dictionary<int, bool> fdr2Dict = new Dictionary<int, bool>();

        List<string> fdr1FileList = new List<string>();
        List<string> fdr2FileList = new List<string>();

        string fdr1Path = folder1_txt.Text;
        string fdr2Path = folder2_txt.Text;

        // File names in the specified directory; path not included
        string[] fdr1FileNames = Directory.GetFiles(fdr1Path).Select(Path.GetFileName).ToArray();
        string[] fdr2FileNames = Directory.GetFiles(fdr2Path).Select(Path.GetFileName).ToArray();

        // Iterate through the first directory, and add GL number to dictionary
        for(int i = 0; i < fdr1FileNames.Length; i++)
        {
            // Grabs only the number from the file name
            string number = Regex.Match(fdr1FileNames[i], @"\d+").ToString();
            int glNumber;

            // Make sure it is a number
            if(Int32.TryParse(number, out glNumber))
            {
                fdr1Dict[glNumber] = true;
            }
            // If number not present, raise exception
            else
            {
                throw new Exception(String.Format("GL Number not found in: {0}", fdr1FileNames[i]));
            }

        }

        // Iterate through the second directory, and add GL number to dictionary
        for (int i = 0; i < fdr2FileNames.Length; i++)
        {
            // Grabs only the number from the file name
            string number = Regex.Match(fdr2FileNames[i], @"\d+").ToString();
            int glNumber;

            // Make sure it is a number
            if (Int32.TryParse(number, out glNumber))
            {
                fdr2Dict[glNumber] = true;
            }
            // If number not present, raise exception
            else
            {
                throw new Exception(String.Format("GL Number not found in: {0}", fdr2FileNames[i]));
            }
        }

       // Iterate through the first directory, and find files that are unique to it
        for (int i = 0; i < fdr1FileNames.Length; i++)
        {
            int glNumber = Int32.Parse(Regex.Match(fdr1FileNames[i], @"\d+").Value);
            // If same file is not present in the second folder add to the list
            if(!fdr2Dict[glNumber])
            {
                fdr1FileList.Add(fdr1FileNames[i]);
            }
        }

        // Iterate through the second directory, and find files that are unique to it
        for (int i = 0; i < fdr2FileNames.Length; i++)
        {
            int glNumber = Int32.Parse(Regex.Match(fdr2FileNames[i], @"\d+").Value);
            // If same file is not present in the first folder add to the list
            if (!fdr1Dict[glNumber])
            {
                fdr2FileList.Add(fdr2FileNames[i]);
            }

我会一次构建每一行。像这样:

int row = 0;
string[] fdr1FileList = new string[0];
string[] fdr2FileList = new string[0];

while (row < fdr1FileList.Length || row < fdr2FileList.Length)
{
    string rowText = "";
    rowText += (row >= fdr1FileList.Length ? "\t" : fdr1FileList[row] + "\t");
    rowText += (row >= fdr2FileList.Length ? "\t" : fdr2FileList[row]);
    row++;
}

尝试这样的事情:

    static void Main(string[] args)
    {
        Dictionary<int, string> fdr1Dict = FilesToDictionary(Directory.GetFiles("path1"));
        Dictionary<int, string> fdr2Dict = FilesToDictionary(Directory.GetFiles("path2"));

        var unique_f1 = fdr1Dict.Where(f1 => !fdr2Dict.ContainsKey(f1.Key)).ToArray();
        var unique_f2 = fdr2Dict.Where(f2 => !fdr1Dict.ContainsKey(f2.Key)).ToArray();

        int f1_size = unique_f1.Length;
        int f2_size = unique_f2.Length;
        int list_length = 0;

        if (f1_size > f2_size)
        {
            list_length = f1_size;
            Array.Resize(ref unique_f2, list_length);
        }
        else
        {
            list_length = f2_size;
            Array.Resize(ref unique_f1, list_length);
        }


        using (StreamWriter writer = new StreamWriter("output.txt"))
        {
            writer.WriteLine(string.Format("{0,-30}{1,-30}", "Unique in fdr1", "Unique in fdr2"));
            for (int i = 0; i < list_length; i++)
            {
                writer.WriteLine(string.Format("{0,-30}{1,-30}", unique_f1[i].Value, unique_f2[i].Value));
            }
        }
    }
    static Dictionary<int, string> FilesToDictionary(string[] filenames)
    {
        Dictionary<int, string> dict = new Dictionary<int, string>();
        for (int i = 0; i < filenames.Length; i++)
        {
            int glNumber;
            string filename = Path.GetFileName(filenames[i]);
            string number = Regex.Match(filename, @"\d+").ToString();

            if (int.TryParse(number, out glNumber))
                dict.Add(glNumber, filename);
        }
        return dict;
    }

我非常有信心这会像我测试过的那样工作:

static void Main(string[] args)
{
    var firstDir = @"Path1";
    var secondDir = @"Path2";

    var firstDirFiles = System.IO.Directory.GetFiles(firstDir);
    var secondDirFiles = System.IO.Directory.GetFiles(secondDir);
    print2Dirs(firstDirFiles, secondDirFiles);

}

private static void print2Dirs(string[] firstDirFile, string[] secondDirFiles)
{
    var maxIndex = Math.Max(firstDirFile.Length, secondDirFiles.Length);

    using (StreamWriter streamWriter = new StreamWriter("result.txt"))
    {
        streamWriter.WriteLine(string.Format("{0,-150}{1,-150}", "Unique in fdr1", "Unique in fdr2"));
        for (int i = 0; i < maxIndex; i++)
        {
            streamWriter.WriteLine(string.Format("{0,-150}{1,-150}",
                firstDirFile.Length > i ? firstDirFile[i] : string.Empty,
                secondDirFiles.Length > i ? secondDirFiles[i] : string.Empty));
        }
    }
}

这是一个非常简单的代码,但如果您需要帮助理解它,请告诉我:)