2016-11-22 6 views
0

ProblemstellungStream C# Formatierung Ausgabe

Um Gen-Annotation-Software zu laufen, ich brauche zwei Arten von Dateien zu erstellen, V-Card-Dateien und Berichterstattung Tabellen, und es eine Eins-zu-Eins-Spiel von zu sein hat vcard zur Abdeckungstabelle. Da ich 2k-Samples verwende, ist es schwer zu erkennen, welche Datei nicht eins zu eins übereinstimmt. Ich weiß, dass beide Dateien eindeutige Kennung Zahlen haben daher, wenn beide Ordner Dateien haben, die gleiche eindeutige Nummern haben, ich behandle, dass als „gleich“


I-Datei ein Programm aus, das zwei Ordner und Berichte eindeutige Einträge vergleicht in jedem Ordner. Um dies zu tun, habe ich zwei Listen erstellt, die eindeutige Dateinamen für jedes Verzeichnis enthalten.

ich die Berichtsdatei (Tab TXT-Datei getrennt) formatiert werden soll, so dass es so etwas wie unten aussieht:

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

ich dies schwer zu tun, weil ich zweimal durchlaufen müssen (da ich zwei Listen), aber es gibt keine Möglichkeit, in StreamWriter zurück zur vorherigen Zeile zu gehen, soweit ich weiß. Wenn ich die erste Liste durchlaufen habe und die erste Spalte gefüllt habe, wie kann ich dann die zweite Spalte mit der zweiten füllen?

Kann mir jemand dabei helfen?

Dank

Wenn Entwurf des Codes ändern muss (dh eine Liste statt zwei), mich bitte

angefordert wissen lassen, wie sie von einigen Benutzern, das ist, wie ich tun würde (nicht Arbeitsversion)

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

Wie für die Suche nach einzigartigen Einträge für meinen Ansatz gebeten, hier ist mein Code-Schnipsel

 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]); 
      } 
+4

Können Sie Ihren Code von dem, was Sie bisher versucht haben, zu posten, so können wir helfen Sie identifizieren das Problem? – Wellspring

+0

Was meinst du mit UNIQUE Eintrag? Jede Datei in einem Verzeichnis hat einen anderen Namen. Meinst du zB 2 Dateien wie 'name.test' und' name.test2'? – Sid

+0

Um eine Problemaussage zu spezifizieren, muss ich zwei Arten von Dateien, vcard-Dateien und Coverage-Tabellen vorbereiten, um gen-Annotationssoftware ausführen zu können, und es muss eine Eins-zu-eins-Übereinstimmung von vcard mit der Coverage-Tabelle bestehen. Da ich 2k-Samples verwende, ist es schwer zu erkennen, welche Datei nicht eins zu eins übereinstimmt. Ich weiß, dass beide Dateien eindeutige Bezeichner Nummern haben, daher, wenn beide Ordner Dateien haben, die gleiche eindeutige Nummern haben, behandle ich das als "gleiche" Datei – djskj189

Antwort

0

ich ziemlich bin zuversichtlich, dass dies funktionieren wird, wie ich es getestet habe:

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

Es ist eine ganz einfache Code, aber wenn Sie Hilfe benötigen zu verstehen, lassen Sie es mich wissen :)

+0

Würde es keine Ausnahme auslösen, wenn zwei Ordner unterschiedliche Anzahl von Dateien haben? wenn list1.Count == 50 und list2.Count == 30, würde es immer noch funktionieren? Oh nein – djskj189

+0

Nein wird es nicht, da ich eine sehr hässliche Methode implementiert habe, um es zu überprüfen. Natürlich können Sie es besser machen, aber ich werde keine Ausnahme machen. Ich habe mit einem Dir mit 1 Datei und anderen mit 3 – Sid

+0

getestet Danke, es hat funktioniert. Wenn Sie eine elegantere Lösung finden, aktualisieren Sie bitte den Beitrag – djskj189

0

Ich würde jede Zeile auf einmal konstruieren. Etwas wie folgt aus:

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

Dies ist genauso zu verursachen und 'IndexOutOfBoundException' – Sid

+0

Es wird nicht, weil es vorher überprüft Zugriff auf das Array, wenn der Index innerhalb der Grenzen liegt (die Zeile> = fdr1FileList.Länge Bit) – Steve

0

versuchen, etwas wie folgt aus:

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

f1.Ausgenommen wird in meinem Fall nicht funktionieren, da Dateien tatsächlich unterschiedliche Namen haben. Sie haben nur die gleichen Identifikationsnummern. Ich wusste nicht, dass das Verwirrung stiften würde, sorry. – djskj189

+0

@ djskj189 also wie hast du vor, die einzigartigen Dateinamen zu bekommen? Können Sie Beispiele für die Dateinamenstruktur bereitstellen? – Innat3

+0

Ich habe Regex verwendet, um die Nummer aus dem Dateinamen zu entfernen. Ich bearbeite den Beitrag, um "Erkenne eindeutigen Dateinamen" -Algorithmus – djskj189