如何解决将具有相同文件名的所有文件移动到C#中的文件夹
我有一个包含一堆文件的文件夹,例如:
example1.mp4
example1-logo.png
example1-footer.png
example2.mp4
example2-logo.png
example2-footer.png
程序应创建2个文件夹,其中包含文件。
example1文件夹:
example1.mp4
example1-logo.png
example1-footer.png
example2文件夹:
example2.mp4
example2-logo.png
example2-footer.png
这是我到目前为止所做的:
using System;
using System.IO;
using System.Windows.Forms;
using Microsoft.WindowsAPICodePack.Dialogs;
CommonOpenFileDialog dialog = new CommonOpenFileDialog();
dialog.Multiselect = true;
dialog.IsFolderPicker = true;
if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
{
foreach (string folder in dialog.FileNames)
{
foreach (string file in Directory.EnumerateFiles(folder))
{
// Do something with the files
}
}
}
else
MessageBox.Show("You must select a folder!",Text,MessageBoxButtons.OK,MessageBoxIcon.Error);
不太确定从这儿去哪里,有什么建议吗?
解决方法
您可以使用破折号分隔符来分割文件名(不带扩展名),以获取字符串数组和第一元素的分组,在您的示例中,第一元素为example1
,第一组为example2
第二个。然后循环 group 以创建目标目录,并循环每个 group 以复制/移动文件。
这是一个例子:
using System.IO;
using System.Linq;
//The caller..
var srcFolder = @"..."; //The source folder.
var desFolder = @"..."; //The destination folder.
var groups = Directory.EnumerateFiles(srcFolder)
.Select(x => new FileInfo(x))
.GroupBy(x => Path.GetFileNameWithoutExtension(x.Name).Split('-').First());
foreach (var group in groups)
{
var groupFolder = Path.Combine(desFolder,group.Key);
Directory.CreateDirectory(groupFolder);
foreach (var file in group)
// Or file.MoveTo(...)
file.CopyTo(Path.Combine(groupFolder,file.Name),true);
}
,
请尝试
CommonOpenFileDialog dialog = new CommonOpenFileDialog();
dialog.Multiselect = true;
dialog.IsFolderPicker = true;
if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
{
Dictionary<string,List<FileInfo>> fileDictionary = new Dictionary<string,List<FileInfo>>();
foreach (string folder in dialog.FileNames)
{
foreach (var file in new DirectoryInfo(folder).GetFiles("*.*",SearchOption.AllDirectories))
{
var existingKey = fileDictionary.Keys.FirstOrDefault(x => file.Name.StartsWith(x));
if (existingKey == null)
{
existingKey = file.Name.Replace(file.Extension,"");
fileDictionary[existingKey] = new List<FileInfo>();
}
fileDictionary[existingKey].Add(file);
}
}
var root = $"{AppDomain.CurrentDomain.BaseDirectory}root";
foreach (var dir in fileDictionary.Keys)
{
var dirName = $"{root}\\{dir}";
if (!Directory.Exists(dirName))
{
Directory.CreateDirectory(dirName);
}
fileDictionary[dir].ForEach(x => x.CopyTo($"{dirName}\\{x.Name}"));
}
}
,
如果他们使用已知的分隔符(您的示例为连字符),则可以读取已发布的例程,直到在文件名中遇到该字符为止。
一旦遇到连字符,请检查是否存在具有基本名称的目录。如果您的工作目录中没有目录,请创建它。然后将要使用其名称的文件复制到新文件中。
我在下面添加了代码,假设'-'是分隔符,文件位于子文件夹中。
class Program
{
static void CopyToTarget(string Target)
{
// this local function scans the given file's name and attempts to extract the
// part before the div char. It also trims whitespaces.
string ExtractName(string Name,char Div)
{
StringBuilder BuildName = new StringBuilder();
if (string.IsNullOrEmpty(Name))
{
return Name;
}
else
{
Name = Name.Trim();
if (Name.Contains(Div))
{
// We walk thru each char and see if it's the Div char
for (int step = 0; step < Name.Length; step++)
{
if (Name[step] == Div)
break;
else
BuildName.Append(Name[step]);
}
// I found the code does not seem to like spaces so this removes them after getting the part of the file I want.
return BuildName.ToString().Trim();
}
else
{
// so we need to figure another way.
// this example just returns the original name
return Name;
}
}
}
foreach (var FileEntry in Directory.EnumerateFiles(Target))
{
string name = ExtractName(Path.GetFileNameWithoutExtension(FileEntry),'-');
string DirTarget = Path.Combine(Target,name);
if (Directory.Exists(DirTarget) == false)
{
Console.WriteLine("Made Directory: " + DirTarget);
Directory.CreateDirectory(DirTarget);
}
else
{
Console.WriteLine("Directory Already Exists: " + DirTarget);
}
DirTarget = Path.Combine(DirTarget,Path.GetFileName(FileEntry));
Console.Write(string.Format("Copying {0} to {1} ",FileEntry,DirTarget));
File.Move(FileEntry,DirTarget);
}
}
static void Main(string[] args)
{
if (args.Length > 0)
CopyToTarget(args[0]);
}
}
,
我试图使所有内容更简单,最易读:
var path = @"X:\Path\To\Target\Folder";
var folder = new DirectoryInfo(path);
var files = folder.GetFiles();
var patterns = new List<Pattern>();
foreach (var file in files)
{
var keyword = Path.GetFileNameWithoutExtension(file.Name);
foreach (var file2 in files)
{
if (file == file2)
continue;
var filename = Path.GetFileNameWithoutExtension(file2.Name);
if (filename.StartsWith(keyword))
{
var pattern = patterns.FirstOrDefault(p => p.Keyword == keyword);
if (pattern == null)
{
patterns.Add(new Pattern
{
Keyword = keyword,Files = new List<FileInfo>() { file,file2 }
});
}
else
{
pattern.Files.Add(file2);
}
}
}
}
foreach (var pattern in patterns)
{
var folder_to_move =Path.Combine( path,pattern.Keyword);
Directory.CreateDirectory(folder_to_move);
foreach (var file in pattern.Files)
file.MoveTo(Path.Combine(folder_to_move,file.Name));
}
这是模式类:
class Pattern
{
public string Keyword { get; set; }
public List<FileInfo> Files { get; set; }
}
我在真实情况下进行了测试,它的工作原理就像魔术:
输出示例
首先显示文件夹内容:
TargetFolder:.
example1-logo2.txt
example1-logo3.txt
example1-movie.txt
example1.txt
example2-logo.txt
example2-video.txt
example2.txt
运行代码后:
TargetFolder:.
├───? example1
│ example1-logo2.txt
│ example1-logo3.txt
│ example1-movie.txt
│ example1.txt
│
└───? example2
example2-logo.txt
example2-video.txt
example2.txt
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。