我的应用程序的输出正在生成重复的文件名...我不是百分之百确定为什么会这样。
我的应用程序通过查找文件名中的正则表达式模式来“清除”文件名。如果没有,则将其转储到“正常”列表中并忽略它。
以下是我用于显示输出的代码:[这一直向我显示文件名的重复!!]
public partial class DriveRecursion_Results : Form
{
List<string> paths = new List<string>();
public DriveRecursion_Results()
{
InitializeComponent();
}
public void DriveRecursion(string retPath)
{
string pattern = (@"[~#&!%+{}]+");
Regex regEx = new Regex(pattern);
string[] fileDrive = Directory.GetFiles(retPath, "*.*", SearchOption.AllDirectories);
List<string> normal = new List<string>();
List<string> fileNameOnlyList = new List<string>();
dataGridView1.Rows.Clear();
try
{
foreach (string fileNames in fileDrive)
{
string strippedFileName = System.IO.Path.GetFileName(fileNames);
fileNameOnlyList.Add(strippedFileName);
foreach (string nameOnly in fileNameOnlyList)
{
if (regEx.IsMatch(strippedFileName))
{
//string fileNameOnly = Path.GetFileName(fileNames);
string pathOnly = Path.GetDirectoryName(fileNames);
DataGridViewRow dgr = new DataGridViewRow();
dgr.CreateCells(dataGridView1);
dgr.Cells[0].Value = pathOnly;
dgr.Cells[1].Value = nameOnly;
dataGridView1.Rows.Add(dgr);
string pathforInvalidName = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(nameOnly), pathOnly);
paths.Add(pathforInvalidName);
}
else
{
normal.Add(strippedFileName);
}
}
}
}
catch (Exception e)
{
StreamWriter sw = new StreamWriter(retPath + "ErrorLog.txt");
sw.Write(e);
}
}
private void button1_Click_1(object sender, EventArgs e)
{
this.Close();
CleanNames clean = new CleanNames();
clean.Sanitizer(paths);
clean.Show();
}
一旦确定需要重命名哪些文件,它就会清除“脏”名称:
public partial class CleanNames : Form
{
public CleanNames()
{
InitializeComponent();
}
public void Sanitizer(List<string> paths)
{
string regPattern = (@"[~#&!%+{}]+");
string replacement = " ";
Regex regExPattern = new Regex(regPattern);
Regex regExPattern2 = new Regex(@"\s{2,}");
StreamWriter errors = new StreamWriter(@"S:\Test\Errors.txt", true);
var filesCount = new Dictionary<string, int>();
dataGridView1.Rows.Clear();
try
{
foreach (string files2 in paths)
{
string filenameOnly = System.IO.Path.GetFileName(files2);
string pathOnly = System.IO.Path.GetDirectoryName(files2);
string sanitizedFileName = regExPattern.Replace(filenameOnly, replacement);
sanitizedFileName = regExPattern2.Replace(sanitizedFileName, replacement);
string sanitized = System.IO.Path.Combine(pathOnly, sanitizedFileName);
if (!System.IO.File.Exists(sanitizedFileName))
{
DataGridViewRow clean = new DataGridViewRow();
clean.CreateCells(dataGridView1);
clean.Cells[0].Value = pathOnly;
clean.Cells[1].Value = filenameOnly;
clean.Cells[2].Value = sanitizedFileName;
dataGridView1.Rows.Add(clean);
System.IO.File.Move(files2, sanitized);
}
else
{
if (filesCount.ContainsKey(sanitizedFileName))
{
filesCount[sanitized]++;
}
else
{
filesCount.Add(sanitized, 1);
}
string newFileName = String.Format("{0}{1}{2}",
System.IO.Path.GetFileNameWithoutExtension(sanitized),
filesCount[sanitized].ToString(),
System.IO.Path.GetExtension(sanitized));
string newFilePath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(sanitized), newFileName);
newFileName = regExPattern2.Replace(newFileName, replacement);
System.IO.File.Move(files2, newFilePath);
sanitized = newFileName;
DataGridViewRow clean = new DataGridViewRow();
clean.CreateCells(dataGridView1);
clean.Cells[0].Value = pathOnly;
clean.Cells[1].Value = filenameOnly;
clean.Cells[2].Value = newFileName;
dataGridView1.Rows.Add(clean);
}
}
}
catch (Exception e)
{
errors.Write(e);
}
}
private void SanitizeFileNames_Load(object sender, EventArgs e)
{ }
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
Application.Exit();
}
我在这里尝试做的只是显示需要重命名的文件(不是所有文件)。我想拿这些脏文件名并用我的第二课清理它们。
有人知道为什么我在输出上看到同一文件的倍数?有谁知道如何解决这个问题?!?!
答案 0 :(得分:5)
我的直接观察是你的foreach (string nameOnly in fileNameOnlyList)
循环不应该嵌套在它的位置。你的逻辑看起来像这样。
For each filename:
Add it to the list.
For *everything in the list*...
所以你要加一个。然后处理它。然后添加另一个。然后处理两个。然后加。然后处理这三个。等等。
试试这个。
foreach (string fileNames in fileDrive)
{
string strippedFileName = System.IO.Path.GetFileName(fileNames);
fileNameOnlyList.Add(strippedFileName);
}
foreach (string strippedFileName in fileNameOnlyList)
{
if (regEx.IsMatch(strippedFileName))
// ...
}
更好的是,为什么有两个循环?
foreach (string fileNames in fileDrive)
{
string strippedFileName = System.IO.Path.GetFileName(fileNames);
fileNameOnlyList.Add(strippedFileName);
if (regEx.IsMatch(strippedFileName))
// ...
}
答案 1 :(得分:0)
我的第一个猜测是你看到重复,因为你在fileNameOnlyList
的循环中有fileDrive
的循环。当您从fileDrive
集合处理第二个文件名时,您也会将第一个文件名添加到数据网格中。
有两种方法可以解决这个问题:
- 将内环移出外环并将其置于其下方
- 删除内部循环(但保留其中的代码)并在代码中使用strippedFileName
而不是nameOnly
变量
答案 2 :(得分:0)
您通过目录结构递归搜索
Directory.GetFiles(retPath, "*.*", SearchOption.AllDirectories);
但您只使用文件名
System.IO.Path.GetFileName(fileNames);
因此,如果嵌套文件夹中有相同的文件,它将显示两次。