none
Ordner kopieren und (wenn vorhanden) mit einer Zahl versehen umbenennen. RRS feed

  • Frage

  • Hallo,

    ich habe ein Projekt wo immer wieder ein Ordner kopiert wird, der aber vom Namen her schon existiert. Beispiel:

    Quelle = d:\Türmessung\425 101

    Neue Messdaten sollen nun kopiert werden. Dieser Ordner 425 101 soll nun auch in den Ordner "Türmessung".

    Windows hängt dann z.B eine '(2) Kopie" an eine Datei dran. Wie geht das aber bei einem Verzeichnis ?

    Die Directory Klasse gibt mir nur eine Exception zurück, dass das Verzeichnis schon existiert.

    Lieben Gruß im voraus.

     

    Dienstag, 12. Februar 2019 13:40

Antworten

  • Hi, wegen der Fehlermeldung, hast du die Pfade auf bei dir gültige Werte angepasst? Kannst du die Fehlermeldung mal komplett hier wiedergeben?

    Ich habe das Beispiel mal in eine Klasse verpackt, die du mit Windows-Forms benutzen kannst:

    In einer Form mit TextBox und 2 Buttons:

    using System;
    using System.Windows.Forms;
    
    namespace WindowsFormsApp1 {
      public partial class Form1 : Form {
        public Form1() {
          InitializeComponent();
          service =
            new FoldersSubfolder(QuellPfad, ZielPfad);
        }
    
        FoldersSubfolder service;
        string QuellPfad = @"d:\türen1";
        string ZielPfad = @"d:\türen2";
    
        private void button1_Click(object sender, EventArgs e) {
          try {
            textBox1.Text = service.GetInfo();
          } catch ( Exception ex ) {
            textBox1.Text = ex.ToString();
          }
        }
    
        private void button2_Click(object sender, EventArgs e) {
          try {
            textBox1.Text = $"{service.Copy()} Dateien kopiert.";
          } catch ( Exception ex ) {
            textBox1.Text = ex.ToString();
          }
        }
      }
    }
    

    Und diesen Klassen:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    
    public class FoldersSubfolder {
      private readonly string _source;
      private readonly string _target;
      private readonly List<string> _sourceFolder = new List<string>();
      private readonly List<FolderPair> _folderPairs = new List<FolderPair>();
    
      // Liefert eine Kopie der Liste...
      public List<FolderPair> GetFolderPairs() =>
        _folderPairs.Select(f => f).ToList();
    
      // ctor
      public FoldersSubfolder(string source, string target) {
        if ( string.IsNullOrWhiteSpace(source) ||
          string.IsNullOrWhiteSpace(target) ) {
          throw new ArgumentNullException();
        }
        _source = source;
        _target = target;
        Prepare();
      }
    
      // Methoden
      public int Copy() {
        var n = 0;
        foreach ( var folderPair in _folderPairs ) {
          n += folderPair.Copy();
        }
        return n;
      }
      public int Move() {
        var n = 0;
        foreach ( var folderPair in _folderPairs ) {
          n += folderPair.Move();
        }
        return n;
      }
      public string GetInfo() {
        StringBuilder sb = new StringBuilder();
        foreach ( FolderPair pair in _folderPairs ) {
          sb.AppendLine(pair.ToString());
        }
        return sb.ToString();
      }
      // Interne Helfer...
      private void Prepare() {
        SeedFolders(_source, _target);
        // Eine Liste aller terminalen Ordner erstellen...
        GetSourceFolder(_source, _source.Length);
        // Jeden Ordner prüfen, dann verarbeiten...
        foreach ( var folder in _sourceFolder ) {
          var sourceFolder = Path.Combine(_source, folder);
          var targetFolder = GetSaveFolder(Path.Combine(_target, folder));
          _folderPairs.Add(new FolderPair(sourceFolder, targetFolder));
        }
      }
      private void GetSourceFolder(string baseFolder, int removeFirstLen) {
        List<string> subFolders = Directory
          .GetDirectories(baseFolder, "*", SearchOption.TopDirectoryOnly)
          .ToList();
        if ( (subFolders?.Count ?? 0) == 0 ) {
          string tf = baseFolder.Substring(removeFirstLen + 1);
          _sourceFolder.Add(tf);
        } else {
          foreach ( var folder in subFolders ) {
            GetSourceFolder(folder, removeFirstLen);
          }
        }
      }
      private string GetSaveFolder(string folder) {
        var i = 0;
        var chk = folder;
        while ( Directory.Exists(chk) ) {
          chk = $"{folder}.({++i})";
        }
        return chk;
      }
      private void SeedFolders(string src, string trg) {
        Seed(src, 0, 10);
        Seed(trg, 5, 15);
    
        void Seed(string folder, int start, int end) {
          if ( !Directory.Exists(folder) ) {
            Directory.CreateDirectory(folder);
            for ( var i = start ; i < end ; i++ ) {
              var subfolder = Path.Combine(folder, $"sub{i}");
              Directory.CreateDirectory(subfolder);
            }
          }
        }
      }
    }
    
    // Struktur, die ein Paar aus Source/Target-Folder beherbergt
    public class FolderPair {
      public readonly string SourceFolder;
      public readonly string TargetFolder;
      public FolderPair(string sourceFolder, string targetFolder) {
        SourceFolder = sourceFolder;
        TargetFolder = targetFolder;
        if ( !Directory.Exists(TargetFolder) ) {
          Directory.CreateDirectory(TargetFolder);
        }
      }
      public int Copy() {
        var files = Directory.GetFiles(SourceFolder);
        foreach ( var sourceFile in files ) {
          var targetFile = Path.Combine(TargetFolder, Path.GetFileName(sourceFile));
          if ( File.Exists(targetFile) ) {
            throw new InvalidOperationException($"Existiert bereits: {targetFile}");
          }
          File.Copy(sourceFile, targetFile);
        }
        return files.Count();
      }
      public int Move() {
        var files = Directory.GetFiles(SourceFolder);
        foreach ( var sourceFile in files ) {
          var targetFile = Path.Combine(TargetFolder, Path.GetFileName(sourceFile));
          File.Move(sourceFile, targetFile);
        }
        return files.Count();
      }
    
      public override string ToString() {
        return $"{SourceFolder} => {TargetFolder}";
      }
    }
    

    Vielleicht kannst du das ja so verwenden?

    Gruß

    • Als Antwort markiert MarkusDB Dienstag, 19. Februar 2019 06:10
    Montag, 18. Februar 2019 15:42

Alle Antworten

  • Hallo Markus,

    Du kannst über die Exists Methode der Directory Klasse prüfen, ob das Zielverzeichnis bereits existiert und falls ja, den Zielverzeichnisnamen entsprechend anpassen und nochmal prüfen (letztendlich solange, bis Exists false zurückgibt oder eine maximale Anzahl an Versuchen erreicht wurde)


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    Dienstag, 12. Februar 2019 13:49
    Moderator
  • Hallo und vielen Dank für die Rückmeldung.

    Leider klappt das so nicht, weil ich zum Zeitpunkt des kopieren nicht weiß wie der Ordner heisst.

    Bei der "if (!Directory.Exists()) " Methode müsste ich ja einen bekannten Ordner eingeben, der dann auf Existens geprüft wird. Oder ?

    MfG Markus

    Samstag, 16. Februar 2019 10:27
  • Hi Markus,
    es ist so:

    if (!Directory.Exists(@"c:\temp\Ordner1")) ….


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP für Developer Technologies)
    Meine Homepage mit Tipps und Tricks

    Samstag, 16. Februar 2019 10:32
  • Leider klappt das so nicht, weil ich zum Zeitpunkt des kopieren nicht weiß wie der Ordner heisst.

    Wenn Du den Namen des Ordners nicht kennst, kannst Du auch nicht kopieren. Also kann das nicht stimmen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    Samstag, 16. Februar 2019 15:54
    Moderator
  • Hi :-))

    Hier mal mein Code. Dieser kopiert alle Unterordner und wenn vorhanden , wird überschrieben. Die Unterordner - Namen sind nicht bekannt.

    Ich will aber nicht überschreiben, sondern einen neuen Zielordner ? irgendwie

    String From = @"C:\Türen";

    String To = @"E:\Türen";

    foreach

    (stringdirPath inDirectory.GetDirectories(From, "*", SearchOption.AllDirectories))

    Directory.CreateDirectory(dirPath.Replace(From, To));

                 

                       

    //Kopiere alle Dateien inklusive Verzeichnisse.                

    foreach(stringnewPath inDirectory.GetFiles(From, "*.*", SearchOption.AllDirectories))

    File.Copy(newPath, newPath.Replace(From, To),

    true);

    Hilfe

    Sonntag, 17. Februar 2019 18:02
  • Hi, in Ergänzung zu bereits gegebenen Anregungen hier ein Beispiel in Form einer Konsolen-Anwendung. Vielleicht hilft es ja weiter...

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    
    namespace CopyFoldersSubfolder {
      class Program {
        static void Main(string[] args) {
          // Quell- und Ziel-Basisverzeichnisse ...
          var source = @"d:\türen";
          var target = @"e:\türen";
          // Beispielordner anlegen...
          SeedFolders(source, target);
    
          // Eine Liste aller terminalen Ordner erstellen...
          GetFolder(source, source.Length);
    
          // Jeden Ordner prüfen, dann verarbeiten...
          foreach ( var folder in terminalFolder ) {
            var sourceFolder = Path.Combine(source, folder);
            var targetFolder = DupCheck(Path.Combine(target, folder));
            
            // Anzeige. Hier die Kopieroperation implementieren 
            Console.WriteLine($"{sourceFolder} => ... => {targetFolder}");
          }
          Console.ReadKey();
        }
    
        static string DupCheck(string folder) {
          var i = 0;
          var chk = folder;
          while ( Directory.Exists(chk) ) {
            chk = $"{folder}.({++i})";
          }
          return chk;
        }
    
        static List<string> terminalFolder = new List<string>();
    
        static void GetFolder(string baseFolder, int removeFirstLen) {
          List<string> subFolders = Directory
            .GetDirectories(baseFolder, "*", SearchOption.TopDirectoryOnly)
            .ToList();
          if ( (subFolders?.Count ?? 0) == 0 ) {
            string tf = baseFolder.Substring(removeFirstLen + 1);
            terminalFolder.Add(tf);
          } else {
            foreach ( var folder in subFolders ) { GetFolder(folder, removeFirstLen); }
          }
        }
    
        static void SeedFolders(string src, string trg) {
          Seed(src, 0, 10);
          Seed(trg, 5, 15);
    
          void Seed(string folder, int start, int end) {
            if ( !Directory.Exists(folder) ) {
              Directory.CreateDirectory(folder);
              for ( var i = start ; i < end ; i++ ) {
                var subfolder = Path.Combine(folder, $"sub{i}");
                Directory.CreateDirectory(subfolder);
              }
            }
          }
        }
      }
    }

    Das sollte auch mit Verzeichnisstrukturen in mehreren Ebenen funktionieren.

    Sonst kannst du es auch noch etwas reduzieren.

    Gruß


    • Bearbeitet K. Pater Sonntag, 17. Februar 2019 23:46
    Sonntag, 17. Februar 2019 23:43
  • Danke. Dein Code ist schonmal SPITZE!

    Ich bekomme das leider nicht in meine Windows Form untergebracht.

    Wenn ich nur die Konsolenanwendung nutze, hab ich das Problem mit dem Fehler "Laufwerk muss im selben Volume liegen.

    Ich weiß nicht wie das über eine Windows Form machen kann.

    Montag, 18. Februar 2019 10:45
  • Hi, wegen der Fehlermeldung, hast du die Pfade auf bei dir gültige Werte angepasst? Kannst du die Fehlermeldung mal komplett hier wiedergeben?

    Ich habe das Beispiel mal in eine Klasse verpackt, die du mit Windows-Forms benutzen kannst:

    In einer Form mit TextBox und 2 Buttons:

    using System;
    using System.Windows.Forms;
    
    namespace WindowsFormsApp1 {
      public partial class Form1 : Form {
        public Form1() {
          InitializeComponent();
          service =
            new FoldersSubfolder(QuellPfad, ZielPfad);
        }
    
        FoldersSubfolder service;
        string QuellPfad = @"d:\türen1";
        string ZielPfad = @"d:\türen2";
    
        private void button1_Click(object sender, EventArgs e) {
          try {
            textBox1.Text = service.GetInfo();
          } catch ( Exception ex ) {
            textBox1.Text = ex.ToString();
          }
        }
    
        private void button2_Click(object sender, EventArgs e) {
          try {
            textBox1.Text = $"{service.Copy()} Dateien kopiert.";
          } catch ( Exception ex ) {
            textBox1.Text = ex.ToString();
          }
        }
      }
    }
    

    Und diesen Klassen:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    
    public class FoldersSubfolder {
      private readonly string _source;
      private readonly string _target;
      private readonly List<string> _sourceFolder = new List<string>();
      private readonly List<FolderPair> _folderPairs = new List<FolderPair>();
    
      // Liefert eine Kopie der Liste...
      public List<FolderPair> GetFolderPairs() =>
        _folderPairs.Select(f => f).ToList();
    
      // ctor
      public FoldersSubfolder(string source, string target) {
        if ( string.IsNullOrWhiteSpace(source) ||
          string.IsNullOrWhiteSpace(target) ) {
          throw new ArgumentNullException();
        }
        _source = source;
        _target = target;
        Prepare();
      }
    
      // Methoden
      public int Copy() {
        var n = 0;
        foreach ( var folderPair in _folderPairs ) {
          n += folderPair.Copy();
        }
        return n;
      }
      public int Move() {
        var n = 0;
        foreach ( var folderPair in _folderPairs ) {
          n += folderPair.Move();
        }
        return n;
      }
      public string GetInfo() {
        StringBuilder sb = new StringBuilder();
        foreach ( FolderPair pair in _folderPairs ) {
          sb.AppendLine(pair.ToString());
        }
        return sb.ToString();
      }
      // Interne Helfer...
      private void Prepare() {
        SeedFolders(_source, _target);
        // Eine Liste aller terminalen Ordner erstellen...
        GetSourceFolder(_source, _source.Length);
        // Jeden Ordner prüfen, dann verarbeiten...
        foreach ( var folder in _sourceFolder ) {
          var sourceFolder = Path.Combine(_source, folder);
          var targetFolder = GetSaveFolder(Path.Combine(_target, folder));
          _folderPairs.Add(new FolderPair(sourceFolder, targetFolder));
        }
      }
      private void GetSourceFolder(string baseFolder, int removeFirstLen) {
        List<string> subFolders = Directory
          .GetDirectories(baseFolder, "*", SearchOption.TopDirectoryOnly)
          .ToList();
        if ( (subFolders?.Count ?? 0) == 0 ) {
          string tf = baseFolder.Substring(removeFirstLen + 1);
          _sourceFolder.Add(tf);
        } else {
          foreach ( var folder in subFolders ) {
            GetSourceFolder(folder, removeFirstLen);
          }
        }
      }
      private string GetSaveFolder(string folder) {
        var i = 0;
        var chk = folder;
        while ( Directory.Exists(chk) ) {
          chk = $"{folder}.({++i})";
        }
        return chk;
      }
      private void SeedFolders(string src, string trg) {
        Seed(src, 0, 10);
        Seed(trg, 5, 15);
    
        void Seed(string folder, int start, int end) {
          if ( !Directory.Exists(folder) ) {
            Directory.CreateDirectory(folder);
            for ( var i = start ; i < end ; i++ ) {
              var subfolder = Path.Combine(folder, $"sub{i}");
              Directory.CreateDirectory(subfolder);
            }
          }
        }
      }
    }
    
    // Struktur, die ein Paar aus Source/Target-Folder beherbergt
    public class FolderPair {
      public readonly string SourceFolder;
      public readonly string TargetFolder;
      public FolderPair(string sourceFolder, string targetFolder) {
        SourceFolder = sourceFolder;
        TargetFolder = targetFolder;
        if ( !Directory.Exists(TargetFolder) ) {
          Directory.CreateDirectory(TargetFolder);
        }
      }
      public int Copy() {
        var files = Directory.GetFiles(SourceFolder);
        foreach ( var sourceFile in files ) {
          var targetFile = Path.Combine(TargetFolder, Path.GetFileName(sourceFile));
          if ( File.Exists(targetFile) ) {
            throw new InvalidOperationException($"Existiert bereits: {targetFile}");
          }
          File.Copy(sourceFile, targetFile);
        }
        return files.Count();
      }
      public int Move() {
        var files = Directory.GetFiles(SourceFolder);
        foreach ( var sourceFile in files ) {
          var targetFile = Path.Combine(TargetFolder, Path.GetFileName(sourceFile));
          File.Move(sourceFile, targetFile);
        }
        return files.Count();
      }
    
      public override string ToString() {
        return $"{SourceFolder} => {TargetFolder}";
      }
    }
    

    Vielleicht kannst du das ja so verwenden?

    Gruß

    • Als Antwort markiert MarkusDB Dienstag, 19. Februar 2019 06:10
    Montag, 18. Februar 2019 15:42
  • Ja was soll ich sagen, der Knaller. Genau das hab ich gesucht. Funktioniert bestens. Ich weiß garnicht ob ich das je selbst auf die Reihe bekommen hätte. Bin damit schon seit Wochen beschäftigt. Vielen lieben Dank für diese Tolle Ausarbeitung! LG Markus
    Dienstag, 19. Februar 2019 06:13
  • Hallo nochmal. Mir ist aufgefallen das die Dateien nicht mit kopiert werden. Hast du da eine Erklärung für ? Ich finde in deinem Quellcode keinen Fehler .
    Mittwoch, 20. Februar 2019 07:33
  • Möglicherweise verwendest du die unter "button1" verwendete Methode GetInfo(). Die liefert dir aber nur Informationen bezüglich der Verzeichnisstrukturen.

    Die Methode Copy() unter "button2" sollte die Dateien kopieren und die Anzahl der kopierten Dateien zurückgeben.

    Die im Beispiel "service" genannte Instanz der Klasse "FoldersSubfolder" hat die Methoden:

    Copy(), Move() und GetInfo(). 

    Ist das vielleicht die Ursache?

    Gruß

    Mittwoch, 20. Februar 2019 22:04
  • Danke für den Denkanstoß. Hatte vergessen den Teil

     textBox1.Text = $"{service.Copy()} Dateien kopiert.";

    einzutragen. Ohne dem läuft nix.

    MfG Markus Koch

    Donnerstag, 21. Februar 2019 09:35