【问题标题】:Move all files in subfolders to another folder将子文件夹中的所有文件移动到另一个文件夹
【发布时间】:2011-04-24 02:52:22
【问题描述】:

我的源路径是C:\Music\,其中有数百个文件夹,分别称为 Album-1、Album-2 等。

我要做的是在我的源路径中创建一个名为 Consolidated 的文件夹。

然后我想将专辑中的所有文件移动到文件夹Consolidated,以便将所有音乐文件放在一个文件夹中。

我该怎么做?

【问题讨论】:

标签: c# directory


【解决方案1】:
    private static void MoveFiles(string sourceDir, string targetDir)
    {
        IEnumerable<FileInfo> files = Directory.GetFiles(sourceDir).Select(f => new FileInfo(f));
        foreach (var file in files)
        {
            File.Move(file.FullName, Path.Combine(targetDir, file.Name));
        }
    }

【讨论】:

  • 为了更加防错,Directory.GetFiles(sourceDir)File.Move(file.FullName,destinationFileName) 要检查目录存在。否则抛出 DirectoryNotFoundException。
【解决方案2】:
class Program
{
    static void Main(string[] args)
    {
        movedirfiles(@"E:\f1", @"E:\f2");
    }
    static void movedirfiles(string sourdir,string destdir)
    {
        string[] dirlist = Directory.GetDirectories(sourdir);

        moveallfiles(sourdir, destdir);
        if (dirlist!=null && dirlist.Count()>0)
        {
            foreach(string dir in dirlist)
            {
                string dirName = destdir+"\\"+ new DirectoryInfo(dir).Name;
                Directory.CreateDirectory(dirName);
                moveallfiles(dir,dirName);
            }
        }

    }
    static void moveallfiles(string sourdir,string destdir)
    {
        string[] filelist = Directory.GetFiles(sourdir);
        if (filelist != null && filelist.Count() > 0)
        {
            foreach (string file in filelist)
            {
                File.Copy(file, string.Concat(destdir, "\\"+Path.GetFileName(file)));
            }
        }
    }

}

【讨论】:

  • 你复制文件而不是移动
【解决方案3】:
        String directoryName = @"D:\NewAll\";
        DirectoryInfo dirInfo = new DirectoryInfo(directoryName);
        if (dirInfo.Exists == false)
            Directory.CreateDirectory(directoryName);

        List<String> AllFiles= Directory
                           .GetFiles(@"D:\SourceDirectory\", "*.*", SearchOption.AllDirectories).ToList();

        foreach (string file in AllFiles)
        {
            FileInfo mFile = new FileInfo(file);

            // to remove name collisions
            if (new FileInfo(dirInfo + "\\" + mFile.Name).Exists == false)
            {
                mFile.MoveTo(dirInfo + "\\" + mFile.Name);
            }
            else
            {
                string s = mFile.Name.Substring(0, mFile.Name.LastIndexOf('.'));

                int a = 0;
                while (new FileInfo(dirInfo + "\\" + s + a.ToString() + mFile.Extension).Exists)
                {
                    a++;
                }
                mFile.MoveTo(dirInfo + "\\" + s + a.ToString() + mFile.Extension);
            }
        }

【讨论】:

    【解决方案4】:

    您可能会发现这有助于删除文件名不同但标题相同的 mp3。

    source from David @ msdn!

    byte[] b = new byte[128];
    string sTitle;
    string sSinger;
    string sAlbum;
    string sYear;
    string sComm;
    FileStream fs = new FileStream(file, FileMode.Open);
    fs.Seek(-128, SeekOrigin.End);
    fs.Read(b, 0, 128);
    bool isSet = false;
    String sFlag = System.Text.Encoding.Default.GetString(b, 0, 3);
    if (sFlag.CompareTo("TAG") == 0)
    {
    System.Console.WriteLine("Tag   is   setted! ");
    isSet = true;
    }
    if (isSet)
    {
    //get   title   of   song; 
    sTitle = System.Text.Encoding.Default.GetString(b, 3, 30);
    System.Console.WriteLine("Title: " + sTitle);
    //get   singer; 
    sSinger = System.Text.Encoding.Default.GetString(b, 33, 30);
    System.Console.WriteLine("Singer: " + sSinger);
    //get   album; 
    sAlbum = System.Text.Encoding.Default.GetString(b, 63, 30);
    System.Console.WriteLine("Album: " + sAlbum);
    //get   Year   of   publish; 
    sYear = System.Text.Encoding.Default.GetString(b, 93, 4);
    System.Console.WriteLine("Year: " + sYear);
    //get   Comment; 
    sComm = System.Text.Encoding.Default.GetString(b, 97, 30);
    System.Console.WriteLine("Comment: " + sComm);
    }
    System.Console.WriteLine("Any   key   to   exit! ");
    System.Console.Read();
    

    【讨论】:

    • 欢迎来到 *。这篇文章不是问题的答案,顺便说一句。已经回答得很好。请不要使用答案来详细说明原始问题。
    【解决方案5】:

    这样试试

    String directoryName = "C:\\Consolidated";
    DirectoryInfo dirInfo = new DirectoryInfo(directoryName);
    if (dirInfo.Exists == false)
        Directory.CreateDirectory(directoryName);
    
    List<String> MyMusicFiles = Directory
                       .GetFiles("C:\\Music", "*.*", SearchOption.AllDirectories).ToList();
    
    foreach (string file in MyMusicFiles)
    {
        FileInfo mFile = new FileInfo(file);
        // to remove name collisions
        if (new FileInfo(dirInfo + "\\" + mFile.Name).Exists == false) 
        {
             mFile.MoveTo(dirInfo + "\\" + mFile.Name);
        }
    }
    

    它将获取“C:\Music”文件夹中的所有文件(包括子文件夹中的文件)并将它们移动到目标文件夹。 SearchOption.AllDirectories 将递归搜索所有子文件夹。

    【讨论】:

    • 什么是文件串通?
    • @gonzobrains 和其他任何人 - 我很确定评论应该是 to remove name *collisions*
    • 文件非法与目录合谋使我们的生活变得困难 - 这就是文件勾结;-)
    • 重要的是,这不会保留子文件夹结构。这可以通过在循环中用 mFile.FullName.Substring(directoryName.TrimEnd('\\').Length+1) 替换 mFile.Name 来调整。
    【解决方案6】:

    MSDN:msdn.microsoft.com/en-us/library/bb762914.aspx

    private void DirectoryCopy(
                string sourceDirName, string destDirName, bool copySubDirs)
            {
                DirectoryInfo dir = new DirectoryInfo(sourceDirName);
                DirectoryInfo[] dirs = dir.GetDirectories();
    
                // If the source directory does not exist, throw an exception.
                if (!dir.Exists)
                {
                    throw new DirectoryNotFoundException(
                        "Source directory does not exist or could not be found: "
                        + sourceDirName);
                }
    
                // If the destination directory does not exist, create it.
                if (!Directory.Exists(destDirName))
                {
                    Directory.CreateDirectory(destDirName);
                }
    
    
                // Get the file contents of the directory to copy.
                FileInfo[] files = dir.GetFiles();
    
                foreach (FileInfo file in files)
                {
                    // Create the path to the new copy of the file.
                    string temppath = Path.Combine(destDirName, file.Name);
    
                    // Copy the file.
                    file.CopyTo(temppath, false);
                }
    
                // If copySubDirs is true, copy the subdirectories.
                if (copySubDirs)
                {
    
                    foreach (DirectoryInfo subdir in dirs)
                    {
                        // Create the subdirectory.
                        string temppath = Path.Combine(destDirName, subdir.Name);
    
                        // Copy the subdirectories.
                        DirectoryCopy(subdir.FullName, temppath, copySubDirs);
                    }
                }
            }
    

    【讨论】:

    【解决方案7】:
     public void MoveDirectory(string[] source, string target)
        {
            var stack = new Stack<Folders>();
            stack.Push(new Folders(source[0], 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[0], 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; 
        } 
    }
    

    【讨论】:

      【解决方案8】:

      基本上,这可以通过 Directory.Move 完成:

                      try
                      {
                          Directory.Move(source, destination);
                      }
                      catch { }
      

      没有任何理由,为什么你不应该使用这个功能。它是递归和速度优化的

      【讨论】:

      • 如果目标目录已经存在怎么办?你应该考虑(在调用Move之前)做一个Directory.Delete(destination, true),如果成功,然后调用Move
      • 这是最好的答案。不需要检查目标文件夹是否存在,执行Directory.Move后源文件夹会被自动删除
      【解决方案9】:

      您可以使用 Directory 对象来执行此操作,但如果您在多个子目录中有相同的文件名(例如,album1\1.mp3、album2\1.mp3),您可能会遇到问题,因此您可能需要一点将一些独特的东西附加到名称上的额外逻辑(例如album1-1.mp4)。

          public void CopyDir( string sourceFolder, string destFolder )
          {
              if (!Directory.Exists( destFolder ))
                  Directory.CreateDirectory( destFolder );
      
              // Get Files & Copy
              string[] files = Directory.GetFiles( sourceFolder );
              foreach (string file in files)
              {
                  string name = Path.GetFileName( file );
      
                  // ADD Unique File Name Check to Below!!!!
                  string dest = Path.Combine( destFolder, name );
                  File.Copy( file, dest );
              }
      
              // Get dirs recursively and copy files
              string[] folders = Directory.GetDirectories( sourceFolder );
              foreach (string folder in folders)
              {
                  string name = Path.GetFileName( folder );
                  string dest = Path.Combine( destFolder, name );
                  CopyDir( folder, dest );
              }
          }
      

      【讨论】:

        【解决方案10】:

        这样的事情应该会让你滚动。你必须添加错误检查,什么不是(如果有一个名为“Consolidated”的源子目录怎么办?如果 Consolidated 已经存在怎么办?等等)这是来自内存,所以请原谅任何语法错误等。

        string source = @"C:\Music";
        string[] directories = Directory.GetDirectories(source);
        string consolidated = Path.Combine(source, "Consolidated")
        Directory.CreateDirectory(consolidated);
        foreach(var directory in directories) {
            Directory.Move(directory, consolidated);
        }
        

        【讨论】:

          【解决方案11】:

          您遍历它们,然后简单地运行Move,Directory 类也具有列出内容的功能 iirc。

          【讨论】: