using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
namespace AFReplace
{
public
partial
class FrmAFReplace : Form
{
private
string _basePath;
private
string _findContent;
private
string _filter;
private
string _replacement;
private
bool _replaceWithRegex;
private
delegate
void DealDelegate(
string workPath);
private List<KeyValue> _lsDealFilesResult;
///
<summary>
///
查找或替换的操作委托
///
</summary>
private DealDelegate _delWork;
///
<summary>
///
当前是否为替换的处理操作
///
</summary>
private
bool _isReplaceDeal;
public FrmAFReplace()
{
InitializeComponent();
Icon = Properties.Resources.file_edit_2;
}
private
void btnReplace_Click(
object sender, EventArgs e)
{
_isReplaceDeal =
true;
_delWork = ReplaceContent;
Work();
}
private
void Work()
{
_basePath = txtDirectory.Text;
if (!Directory.Exists(_basePath))
{
tsslblMessage.Text =
"
路径不存在
";
return;
}
DirectoryInfo basePathInfo =
new DirectoryInfo(_basePath);
_filter = txtFilter.Text;
if (
string.IsNullOrEmpty(_filter))
{
tsslblMessage.Text =
"
文件筛选输入为空
";
return;
}
_findContent = txtFindContent.Text;
if (
string.IsNullOrEmpty(_findContent))
{
tsslblMessage.Text =
"
查找内容输入为空
";
return;
}
_replacement = txtReplaceContent.Text;
_replaceWithRegex = ckbReplaceWithRegex.Checked;
_lsDealFilesResult =
new List<KeyValue>();
if (ckbDirectoryItem.Checked)
{
new Thread(() => WorkInDirectoryDeep(basePathInfo)).Start();
}
else
{
new Thread(() => WorkInDirectory(basePathInfo)).Start();
}
}
///
<summary>
///
仅在指定目录替换
///
</summary>
///
<param name="dirInfo"></param>
private
void WorkInDirectory(DirectoryInfo dirInfo)
{
WorkByDirectoryInfo(dirInfo);
WorkedAfter();
}
private
void WorkByDirectoryInfo(DirectoryInfo dirInfo)
{
if (dirInfo.Exists)
{
_delWork(dirInfo.FullName);
}
}
private
void WorkedAfter()
{
ShowFindResult();
}
///
<summary>
///
深入到子目录替换
///
</summary>
///
<param name="dirInfo"></param>
private
void WorkInDirectoryDeep(DirectoryInfo dirInfo)
{
WorkByDirectoryInfo(dirInfo);
DirectoryInfo[] lsDirInfo = dirInfo.GetDirectories();
if (lsDirInfo.Length >
0)
{
foreach (DirectoryInfo info
in lsDirInfo)
{
WorkInDirectory(info);
}
}
else
{
ShowMessage(
"
操作完成
");
WorkedAfter();
}
}
///
<summary>
///
在指定目录查找指定文件,并替换,保存。
///
</summary>
///
<param name="workPath"></param>
private
void ReplaceContent(
string workPath)
{
string[] files = Directory.GetFiles(workPath, _filter);
string value;
foreach (
string file
in files)
{
string content = File.ReadAllText(file);
content = _replaceWithRegex ? Regex.Replace(content, _findContent, ReplaceDeal) : content.Replace(_findContent, _replacement);
byte[] buffer = Encoding.UTF8.GetBytes(content);
if (
new FileInfo(file).IsReadOnly)
{
value =
"
文件只读 >
" + Path.GetFileName(file);
}
else
{
File.Delete(file);
using (FileStream fs =
new FileStream(file, FileMode.Create, FileAccess.Write))
{
fs.Write(buffer,
0, buffer.Length);
}
value =
"
已处理 >
" + Path.GetFileName(file);
}
ShowMessage(value);
_lsDealFilesResult.Add(
new KeyValue(file, value));
}
}
///
<summary>
///
在指定目录查找指定文件
///
</summary>
///
<param name="workPath"></param>
private
void FindFiles(
string workPath)
{
string[] files = Directory.GetFiles(workPath, _filter);
foreach (
string file
in files)
{
string content = File.ReadAllText(file);
bool isMatch = _replaceWithRegex ? Regex.IsMatch(content, _findContent) : content.Contains(_findContent);
if (isMatch)
{
_lsDealFilesResult.Add(
new KeyValue(file, file));
}
}
}
///
<summary>
///
正则替换
///
</summary>
///
<param name="m"></param>
///
<returns></returns>
private
string ReplaceDeal(Match m)
{
if (m.Success)
{
MatchCollection mc = Regex.Matches(_replacement,
@"
{(?<value>\d+)}
");
List<
int> lsValueIndex =
new List<
int>();
foreach (Match match
in mc)
{
int iValueIndex =
int.Parse(match.Groups[
"
value
"].Value);
//
序号不可以大于查找到的集合数,总数为匹配()数+自身1
if (iValueIndex > m.Groups.Count)
throw
new Exception(
"
替换的匹配数错误
");
if (!lsValueIndex.Contains(iValueIndex))
lsValueIndex.Add(iValueIndex);
}
return lsValueIndex.Aggregate(_replacement, (current, i) => current.Replace(
"
{
" + i +
"
}
", m.Groups[i].Value));
}
return
"";
}
private
void ShowMessage(
string msg)
{
if (InvokeRequired)
{
Invoke(
new MethodInvoker(() => ShowMessage(msg)));
}
else
{
tsslblMessage.Text = msg;
}
}
private
void ShowFindResult()
{
if (InvokeRequired)
{
Invoke(
new MethodInvoker(ShowFindResult));
}
else
{
new FrmDealResult(_lsDealFilesResult, _isReplaceDeal ?
"
替换结果
" :
"
查找结果
").Show();
}
}
private
void lblAbout_Click(
object sender, EventArgs e)
{
MessageBox.Show(
"
bug及建议提交,请联系[email protected]
",
"
查找替换
", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private
void ckbReplaceWithRegex_CheckedChanged(
object sender, EventArgs e)
{
toolTip1.SetToolTip(txtReplaceContent,
ckbReplaceWithRegex.Checked ?
"
可以使用{index}进行后向引用,{1}{2}={2}{1}。序号从1开始,0为匹配到的整个值。
" :
"");
}
private
void btnFind_Click(
object sender, EventArgs e)
{
_isReplaceDeal =
false;
_delWork = FindFiles;
Work();
}
private
void txtDirectory_TextChanged(
object sender, EventArgs e)
{
toolTip1.SetToolTip(txtDirectory, txtDirectory.Text.Length >
45 ? txtDirectory.Text :
"");
}
private
void tsslblViewDealList_Click(
object sender, EventArgs e)
{
ShowFindResult();
}
private
void btnOpenDirectory_Click(
object sender, EventArgs e)
{
if (Directory.Exists(txtDirectory.Text))
{
Process.Start(txtDirectory.Text);
}
}
private
void btnSelectDirectory_Click(
object sender, EventArgs e)
{
var fbd =
new FolderBrowserDialog();
if (fbd.ShowDialog() == DialogResult.OK)
{
txtDirectory.Text = fbd.SelectedPath;
}
}
}
}