2017-02-16 1 views
-5

Par exemple, j'ai FILE1.TXT et ci-dessous le contenu du fichiercomment diviser le chemin du fichier basé sur le dossier

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 

Maintenant, en lisant ci-dessus fichier ligne par ligne souhaitez créer un autre fichier .. dire fichier 2 avec le contenu ci-dessous

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

Qu'avez-vous essayé jusqu'à présent? –

+0

Il y a au moins une erreur: * test1 \ abc \ .n.cs * n'est pas dans le second fichier – xanatos

+0

Copie possible de [fichier texte: Lecture ligne par ligne C#] (http://stackoverflow.com/questions/ 21861505/text-file-lecture-line-by-line-c-sharp) –

Répondre

0

il est assez complexe pour le faire correctement, je pense ....

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

puis:

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

Notez que je vais dans un IEnumerable<> à la fois comme source et comme destination, et j'utiliser les File.ReadLines surcharges/File.WriteAllLines qui acceptent IEnumerable<>

1

Vous pouvez énumérer comme ça dans une assez simple chemin:

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

    } 
} 

Pour obtenir les lignes individuelles de votre fichier d'origine, vous pouvez utiliser ReadAllLines

Exemple en direct: http://rextester.com/YBOGIH60970

+0

Le 'ToList()' est inutile. 'Split' renvoie un tableau. En le supprimant, vous devez changer '.Count' ->' .Length'. Très bonne idée d'utiliser le '.Take()' :-) – xanatos

+0

@xanatos merci. J'ai oublié de ranger après une itération précédente. – Jamiec