StreamWriter C#格式化输出

时间:2016-11-22 15:54:33

标签: c# streamwriter

问题陈述

为了运行基因注释软件,我需要准备两种类型的文件,即vcard文件和覆盖表,并且必须与vcard和coverage表进行一对一的匹配。由于我运行2k样本,很难识别哪个文件不是一对一匹配。我知道这两个文件都有唯一的标识号,因此,如果两个文件夹中的文件具有相同的唯一编号,我将其视为"相同"文件

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

我想格式化报告文件(制表符分隔的.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]);
            }

3 个答案:

答案 0 :(得分:0)

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

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++;
}

答案 1 :(得分:0)

尝试这样的事情:

    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;
    }

答案 2 :(得分:0)

我非常有信心,这会在我测试过的时候起作用:

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));
        }
    }
}

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