由于项目需要,我写了一个初始MySQL数据库的工具;
一, 思路:
(1),首先读取包含mysql语句的脚本(其中有创建数据库,表,插入初始数据等!)。
(2),然后替换里面的一些数据值(如guid,注释等!)。
(3),把替换后的数据流重新写入mysql脚本。
(4),调用MySQL命令执行相应的命令。
主要思路结束!
二, 现具体过程如下:
1,主界面如图:
2,全局代码和构造方法如下:
Code
stringIP;
stringuserName;
stringuserPwd;
stringpath;
stringmesg="";
Boolean info=false;
//字符串形式的guid
string_guID="";
stringtimeMesg="";
inti=0;
//测量间隔运行时间
Stopwatch stop=newStopwatch();
publicToolForm()
{
InitializeComponent();
}
3,在按钮事件中验证了各个文本框中的值是否为空;IP地址和端口号的验证!
代码如下:
Code
/**
///按钮事件
///
///
///
privatevoidbtnOK_Click(objectsender, EventArgs e)
{
i=0;
this.lbMessage.Text="";
IP=this.tbIP.Text.Trim();
userName=this.tbUserName.Text.Trim();
userPwd=this.tbPWD.Text.Trim();
DirPath=Application.StartupPath;
Regex regexIP=newRegex(@"^((0|1[0-9]{0,2}|2[0-9]{0,1}|2[0-4][0-9]|25[0-5]|[3-9][0-9]{0,1})\.){3}(0|1[0-9]{0,2}|2[0-9]{0,1}|2[0-4][0-9]|25[0-5]|[3-9][0-9]{0,1})$");
if(string.IsNullOrEmpty(IP))
{
MessageBox.Show("请输入服务器地址!");
this.tbIP.Focus();
return;
}
elseif(string.IsNullOrEmpty(userName))
{
MessageBox.Show("请输入用户名!");
this.tbUserName.Focus();
return;
}
elseif(string.IsNullOrEmpty(userPwd))
{
MessageBox.Show("请输入密码!");
this.tbPWD.Focus();
return;
}
elseif(regexIP.IsMatch(IP)||(string.Compare(IP,"localhost",true)==0))
{
//得到目录下的所有文件
string[] files=Directory.GetFiles(DirPath);
//循环读文件
foreach(stringfileinfiles)
{
//如果后缀名为.sql文件
if(".sql".IndexOf(file.Substring(file.LastIndexOf(".")+1))>-1)
{
//把.sql文件全名加人到fileList集合中
fileList.Add(file);
}
}
if(fileList.Count>1)
{
MessageBox.Show("目录下多个.sql文件!该程序只能读一个!");
return;
}
elseif(fileList.Count<1)
{
MessageBox.Show("目录下没有.sql文件!");
return;
}
else
{
path=fileList.First();
this.lbMessage.Text="正在导入数据!请稍等
..";
//测量时间开始
stop.Start();
//调用主方法
MainMethod();
}
}
else
{
MessageBox.Show("服务器IP地址不规范!");
this.tbIP.Focus();
return;
}
}
4, 如果输入符和规范,则调用主方法(主方法里实现思路中主要方法的调用);
主方法代码如下:
Code
/**
///主方法
///
///
///
///
///
///
privatevoidMainMethod()
{
try
{
//读文件
stringfileRed=ReadSQLFromFile(path);
//写文件
File.WriteAllText(path, fileRed);
//调用进度条的timer
this.timer1.Start();
//调用执行脚本文件的timer
this.timer2.Start();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
5, 读脚本文件,替换guid标识的方法;
代码如下:
Code
/**
///读文件流,替换guid标示
///
///
///
///
privatestringReadSQLFromFile(stringpath)
{
//新生成一个guid
Guid guId=Guid.NewGuid();
//把guid转换为字符串形式的guid
_guID="{"+guId+"}";
FileStream fs=null;
stringstrQuery="";
try
{
fs=newFileStream(path, FileMode.Open, FileAccess.Read);
stringstrTemp=Encoding.UTF8.GetString(ConvertStreamToByteBuffer(fs));
//用新生成的guid替换掉脚本文件中的guid;
strQuery=Regex.Replace(strTemp,@"(\{[A-Fa-f0-9]{8}(-[A-Fa-f0-9]{4}){3}-[A-Fa-f0-9]{12}\})+", _guID, RegexOptions.Singleline);
intindexValue=strQuery.IndexOf("USE")+3;
intindexStart=indexValue;
intindexEnd=0;
while(strQuery.Substring(indexValue,1)!=";")
{
indexValue++;
indexEnd=indexValue;
}
DBName=strQuery.Substring(indexStart, (indexEnd-indexStart));
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
strQuery="";
}
finally
{
fs.Close();
}
returnstrQuery;
}
6,把替换后的字符串写入脚本文件:
代码如下:
Code
File.WriteAllText(path, fileRed);
7,然后是开启两个timer,一个控制进度条,另一个获取执行时间的间隔。这里略。。。
8,在获取执行时间的timer事件中,调用执行脚本文件的方法。
该方法的代码如下:
Code
/**
///调用mysql命令来执行脚本文文件
///
///
///
///
///
///
publicstringRunCmd()
{
Stopwatch a=newStopwatch();
lnotallow=a.ElapsedMilliseconds;
stringmesg="";
stringmesgError="";
Process p=null;
try
{
进入cmd调用mysql命令来执行脚本文件#region进入cmd调用mysql命令来执行脚本文件
p=newProcess();
p.StartInfo.FileName="cmd.exe";
p.StartInfo.UseShellExecute=false;
p.StartInfo.RedirectStandardInput=true;
p.StartInfo.RedirectStandardOutput=true;
p.StartInfo.RedirectStandardError=true;
p.StartInfo.CreateNoWindow=true;
p.Start();
//p.StandardInput.WriteLine(@"net start mysql");
p.StandardInput.WriteLine(@"c:");
p.StandardInput.WriteLine(@"cd C:\Program Files\MySQL\MySQL Server 5.0\bin");
p.StandardInput.WriteLine(string.Format("mysql.exe -h{0} -u{1} -p{2} -f{3}\"", IP, userName, userPwd, path));
p.StandardInput.WriteLine("exit");
mesgError=p.StandardError.ReadToEnd();
mesg=mesgError;
p.WaitForExit();
#endregion
}
catch(Exception err)
{
//MessageBox.Show(err.Message);//显示错误信息。
mesg=err.Message;
}
finally
{
p.Close();
}
returnmesg;
}
9,把给定的文件流转换为二进制字节数组的方法,
代码如下:
Code
把给定的文件流转换为二进制字节数组byte[] ConvertStreamToByteBuffer(System.IO.Stream theStream)#region把给定的文件流转换为二进制字节数组byte[] ConvertStreamToByteBuffer(System.IO.Stream theStream)
/**
///把给定的文件流转换为二进制字节数组。
///
///
///
publicbyte[] ConvertStreamToByteBuffer(System.IO.Stream theStream)
{
intb1;
System.IO.MemoryStream tempStream=newSystem.IO.MemoryStream();
while((b1=theStream.ReadByte())!=-1)
{
tempStream.WriteByte(((byte)b1));
}
returntempStream.ToArray();
}
#endregion
10,控制进度条的timer事件;
代码如下:
Code//控制进度条显示/privatevoidtimer1_Tick(objectsender, EventArgs e)
{try{this.progressBar1.Value=i;
i+=10;if(i==1000)
{this.timer1.Stop();if(string.IsNullOrEmpty(mesg)&&info)
{
lbMessage.Text="数据导入成功!"+timeMesg;newMCFrom(_guID, IP, userName, userPwd, DBName).ShowDialog();
}else{
lbMessage.Text="数据导入失败!";
}
stop.Reset();
}
}catch(System.Exception )
{
}
}
11,获取执行时间间隔的time事件;
代码如下:
Code
/**
///调用执行脚本文件的方法,并得到从点击按钮到成功导入数据库后的间隔时间。
///
///
///
privatevoidtimer2_Tick(objectsender, EventArgs e)
{
//执行文件中的命令
mesg=RunCmd();
this.timer2.Stop();
info=true;
timeMesg=stop.Elapsed.Seconds.ToString()+"秒";
stop.Stop();
}
12,整个小工具大体的程序代码完成!有些细节省略掉了 !请在我的随笔里查看!