2010-03-31 18 views
16

मैं मुख्य फ़ोल्डर मिल गया है काम नहीं करता है:Directory.Move (फ़ाइल पहले से ही मौजूद हैं)

c:\test 

और वहाँ मैं 2 फ़ोल्डर: सिनेमा और तस्वीरें। लोगों, जानवरों और इमारतों:

तस्वीरें एक ही संरचना के साथ फाइलों के साथ तीन फ़ोल्डर होते हैं। मैं इस कोड कोशिश कर रहा हूँ:

Directory.Move(@"c:\test\Movies", @"c:\test\Test"); 

मैं अपवाद:

File already exists 

उत्तर

31

यह विधि एक फ़ोल्डर की सामग्री को दोबारा स्थानांतरित करेगी और मौजूदा फ़ाइलों को ओवरराइट करेगा।
आपको कुछ अपवाद हैंडलिंग जोड़ना चाहिए।
संपादित करें:
यह विधि थोड़ी देर के लूप और रिकर्सन के बजाय एक स्टैक के साथ लागू की गई है।

public static void MoveDirectory(string source, string target) 
{ 
    var stack = new Stack<Folders>(); 
    stack.Push(new Folders(source, target)); 

    while (stack.Count > 0) 
    { 
     var folders = stack.Pop(); 
     Directory.CreateDirectory(folders.Target); 
     foreach (var file in Directory.GetFiles(folders.Source, "*.*")) 
     { 
      string targetFile = Path.Combine(folders.Target, Path.GetFileName(file)); 
      if (File.Exists(targetFile)) File.Delete(targetFile); 
      File.Move(file, targetFile); 
     } 

     foreach (var folder in Directory.GetDirectories(folders.Source)) 
     { 
      stack.Push(new Folders(folder, Path.Combine(folders.Target, Path.GetFileName(folder)))); 
     } 
    } 
    Directory.Delete(source, true); 
} 
public class Folders 
{ 
    public string Source { get; private set; } 
    public string Target { get; private set; } 

    public Folders(string source, string target) 
    { 
     Source = source; 
     Target = target; 
    } 
} 

अद्यतन:
यह Directory.EnumerateFiles के उपयोग रिकर्सिवली बजाय के ढेर का उपयोग कर के साथ एक सरल संस्करण है।
यह केवल .net 4 के साथ बाद में, हमें यह करने के लिए Directory.GetFiles को .net परिवर्तन Directory.EnumerateFiles के पिछले संस्करण के साथ काम या होगा।

public static void MoveDirectory(string source, string target) 
{ 
    var sourcePath = source.TrimEnd('\\', ' '); 
    var targetPath = target.TrimEnd('\\', ' '); 
    var files = Directory.EnumerateFiles(sourcePath, "*", SearchOption.AllDirectories) 
         .GroupBy(s=> Path.GetDirectoryName(s)); 
    foreach (var folder in files) 
    { 
     var targetFolder = folder.Key.Replace(sourcePath, targetPath); 
     Directory.CreateDirectory(targetFolder); 
     foreach (var file in folder) 
     { 
      var targetFile = Path.Combine(targetFolder, Path.GetFileName(file)); 
      if (File.Exists(targetFile)) File.Delete(targetFile); 
      File.Move(file, targetFile); 
     } 
    } 
    Directory.Delete(source, true); 
} 
+1

एक महान समाधान जो कि बदले में बदले में बहुत सुधार करता है। –

+0

यह विधि रिकर्सन से बेहतर क्यों है? – Daniel

+0

मेरी समस्या यह है कि यह प्रतिलिपि के दौरान फ़ाइल लॉक है और बहुत ही अंत निर्देशिका में उपलब्ध हो जाती है। हटाएं (स्रोत, सत्य) इसे हटा देगा। – Daniel

7

गंतव्य निर्देशिका पहले से मौजूद नहीं चाहिए - Directory.Move विधि आपके लिए गंतव्य निर्देशिका बनाता है।

0

यह आप इसे करने के लिए नए सामग्री की प्रतिलिपि से पहले गंतव्य फ़ोल्डर को हटाने के लिए के लिए सुरक्षित है?

Directory.Delete(@"c:\test\test"); 
    Directory.Move(@"c:\test\movies",@"c:\test\test"); 
+0

दुर्भाग्य से नहीं ... – user278618

0

सबसे आम 2 वजहों Directory.Move विफल हो सकता है, कर रहे हैं:

  • यह एक अलग मात्रा (आप कॉपी/हटाने की आवश्यकता)
  • यह पहले से ही मौजूद है (अधिलेखित का समर्थन नहीं करता डिफ़ॉल्ट रूप से)

यहाँ दूसरी समस्या के लिए मेरे सरल समाधान (अधिलेखित) है:

public bool MoveDirectory(string sourceDirName, string destDirName, bool overwrite) 
{ 
    if (overwrite && Directory.Exists(destDirName)) 
    { 
     var needRestore = false; 
     var tmpDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); 
     try 
     { 
      Directory.Move(destDirName, tmpDir); 
      needRestore = true; // only if fails 
      Directory.Move(sourceDirName, destDirName); 
      return true; 
     } 
     catch (Exception) 
     { 
      if (needRestore) 
      { 
       Directory.Move(tmpDir, destDirName); 
      } 
     } 
     finally 
     { 
      Directory.Delete(tmpDir, true); 
     } 
    } 
    else 
    { 
     Directory.Move(sourceDirName, destDirName); // Can throw an Exception 
     return true; 
    } 
    return false; 
} 
+1

इस कोड में यह मुद्दा है कि यदि Move (destDirName, tmpDir) विफल रहता है, तो आखिरकार हटाएं (tmpDir) पर एक अपवाद फेंक दिया जाएगा। –

+0

क्या इस सामान्य विंडोज़ क्रिया को करने के लिए सी # के लिए कोई अंतर्निहित तरीका नहीं है? –

1
ProcessStartInfo p = new ProcessStartInfo("cmd", "/c move \"c:\\test\\Movies\" \"c:\\test\Test\\""); 
p.WindowStyle = ProcessWindowStyle.Hidden; //hide mode 
Process.Start(p); 
संबंधित मुद्दे