2017-02-16 15 views
-5

Zum Beispiel habe ich file1.txt und unten ist, den Inhalt der Dateiwie den Dateipfad teilen, basierend auf Ordner

test1\abc\a.xml 
test1\abc\n.cs 
test1\HB\proc1\candidate1\rel1\spy\can.xml 
test1\HB\proc1\candidate1\rel1\spy\globals.xml 
test1\HB\proc1\candidate1\rel1\spy\mike.cs 

nun über Datei Zeile für Zeile durch das Lesen möchte eine andere Datei erstellen .. Datei sagt 2 mit dem folgenden Inhalt

test1\abc 
test1\abc\a.xml 
test1\abc\n.xml 
test1\HB 
test1\HB\proc1 
test1\HB\proc1\candidate1 
test1\HB\proc1\candidate1\rel1 
test1\HB\proc1\candidate1\rel1\spy 
test1\HB\proc1\candidate1\rel1\spy\can.xml 
test1\HB\proc1\candidate1\rel1\spy\globals.xml 
test1\HB\proc1\candidate1\rel1\spy\mike.cs 
+2

Was haben Sie bisher versucht? –

+0

Es gibt mindestens einen Fehler: * test1 \ abc \ .n.cs * ist nicht in der zweiten Datei – xanatos

+0

Mögliche Duplikate von [Textdatei: Zeile für Zeile C# lesen] (http://stackoverflow.com/questions/ 21861505/Textdatei-Lesen-Zeile-für-Zeile-c-sharp) –

Antwort

0

es ist ziemlich komplex um es richtig zu tun, denke ich ....

var filenames = File.ReadLines("source.txt"); 
var result = ExpandFilenames(filenames); 
File.WriteAllLines("dest.txt", result); 

und dann:

static IEnumerable<string> ExpandFilenames(IEnumerable<string> filenames) { 
    var alreadyDone = new HashSet<string>(); 

    foreach (string fileName in filenames) { 
     string directoryName = Path.GetDirectoryName(fileName); 

     // "Expand" the parent directories 
     var expandedDirectories = ExpandDirectories(directoryName, alreadyDone); 

     foreach (string dir in expandedDirectories) { 
      yield return dir; 
     } 

     yield return fileName; 
    } 
} 

// Recursive yield :-) I do know it is slow, but it is easy to write :-) 
static IEnumerable<string> ExpandDirectories(string directoryName, HashSet<string> alreadyDone) { 
    if (directoryName == string.Empty || alreadyDone.Contains(directoryName)) { 
     yield break; 
    } 

    // We "cheat": we use Path.GetDirectoryName to get the name of 
    // the "parent" directory 
    string directoryName2 = Path.GetDirectoryName(directoryName); 

    if (directoryName2 != null) { 
     var expandedDirectories = ExpandDirectories(directoryName2, alreadyDone); 

     foreach (string dir in expandedDirectories) { 
      yield return dir; 
     } 
    } 

    alreadyDone.Add(directoryName); 
    yield return directoryName; 
} 

Bitte beachte, dass ich durch eine IEnumerable<> sowohl als Quelle als auch als Ziel werde, und ich verwende die File.ReadLines/File.WriteAllLines Überlastungen, die IEnumerable<>

1

akzeptieren So können Sie wie dies in einer relativ einfach aufzählen übrigens:

public static IEnumerable<string> EnumerateAllPaths(string[] input) 
{ 
    var hs = new HashSet<string>(); 

    foreach(var s in input) 
    { 
     var parts = s.Split(new[]{@"\"},StringSplitOptions.None); 

     for(var i = 0;i<parts.Length;i++) 
     { 
      var section = String.Join(@"\", parts.Take(i+1)); 
      if(hs.Add(section)) 
       yield return section; 
     } 

    } 
} 

Um die einzelnen Zeilen aus Ihrer ursprünglichen Datei erhalten Sie verwenden können ReadAllLines

Live-Beispiel: http://rextester.com/YBOGIH60970

+0

Die 'ToList()' ist nutzlos. 'Split' gibt ein Array zurück. Wenn Sie es entfernen, müssen Sie '.Count' ->' .Length' ändern. Sehr gute Idee der Verwendung der '.Take()' :-) – xanatos

+0

@xanatos danke. Ich habe vergessen, nach einer vorherigen Iteration aufzuräumen. – Jamiec

Verwandte Themen