windows hosts 文件读写小工具

来源:互联网 发布:c和a的算法 编辑:程序博客网 时间:2024/05/21 08:01

         asp.net新项目开发完毕,需要让测试人员在内网进行测试。http://110.110.110.110/logon.aspx这样的地址看着不舒服,http://test.a.com/logon.aspx这看着就舒服。在测试阶段,可以不动用dns。在windows系统对域名的解析,有一个比dns优先级更高的机制:hosts文件。系统对一个域名,先是找C:\WINDOWS\system32\drivers\etc\hosts文件中定义的ip地址映射,找不到才会去dns解析。基于此,测试阶段,不动用dns的情况下,可以让测试人员在自己电脑上修改hosts文件,使测试地址映射到测试服务器的ip;测试服务器地址变动或测试结束后进行调整/删除。为了方便测试人员,本人用C#写个WinForm小工具来完成对hosts文件的增删操作。(小麻雀仅有增删;改:先删再增)

        先看C:\WINDOWS\system32\drivers\etc\hosts文件的域名-IP映射格式:

#      102.54.94.97     rhino.acme.com          # source server127.0.0.1       localhost  110.110.110.110 test.a.com #注释120.120.120.120 test.a.com    #注释


         每行中#后面的文字是注释。对于注释之外的有效文字,每行一个映射(行首可以是空白字符),如上述映射就将test.a.com域名映射到110.110.110.110服务器。同名的域名出现多次的话,第一个有效,如上述示例中,紧接着的120.120.120.120被忽视。当然,可以有多个不同的域名映射到相同IP地址。

        现在来完成一个用来操作hosts文件的小工具,仅提供增加映射和删除映射功能。先看几个关键点。

        1.判断指定域名的映射是否存在。由正则表达式方便完成:

//strDomain 是待检查存在否的域名//有效映射行(行首到IP地址之间有0个以上空白字符,IP与域名间有1个以上空白字符,行末0个以上注释)Regex regMapping = new Regex(@"^\s*\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s+" + strDomain + @"\s*(#.*)*$");

        2.添加域名映射的实现方法:

        逐行读取hosts文件,暂存入StringBuilder,在StringBuilder最后加入用户输入的域名、IP、备注三个字符串组成的映射(IP 域名 #备注),将StringBuilder内容覆盖hosts文件。

        过程中将读到的每一行用regMapping检查,如果match,说明指定域名的映射已存在,将改行用MessageBox show出来,终止,不再进行后续的读取和覆盖。

        3.删除指定域名的映射方法:

        逐行读取hosts文件,将读到的每一行用regMapping检查,如果不match,将该行暂存入StringBuilder(如果match就不存),最后将StringBuilder内容覆盖hosts文件。

        过程中,如果逐行读取hosts完毕仍然没找到一行match,说明指定域名的映射不存在,提示,终止,不再进行覆盖操作。

        一些细节,如用Regex校验用户输入的IPv4地址,窗口置顶,按钮提示文字等不在这里赘述。

        这里贴出关键的增删代码。

        //删除指定域名的所有映射 throws Exception        private void DeleteHostMapping(string strDomain)        {            if (!File.Exists(hostMappingFile))            {                MessageBox.Show("未执行删除!\n文件不存在:\n" + hostMappingFile, "提示");                return;            }            //有效映射行(行首到IP地址之间有0个以上空白字符,IP与域名间有1个以上空白字符,行末0个以上注释)            Regex regMapping = new Regex(@"^\s*\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s+" + strDomain + @"\s*(#.*)*$");            //待写入文件的内容            StringBuilder sbFinalContent = new StringBuilder();            //待删除域名映射(正常情况下只会有一条记录,考虑文件被手工修改的情况,需要删除全部映射,新的域名映射才会生效)            List<string> host2Delete = new List<string>();            //删除(读取系统原有映射,过滤掉指定域名的映射)            using (StreamReader sr = new StreamReader(hostMappingFile))            {                string tmpLine = sr.ReadLine();                while (tmpLine != null)                {                    if (regMapping.IsMatch(tmpLine))                    {                        host2Delete.Add(tmpLine);                    }                    else                    {                        sbFinalContent.Append(tmpLine);                        sbFinalContent.AppendLine();                    }                    tmpLine = sr.ReadLine();                }            }            //不存在,所以文件没做更改,无需写入覆盖            if (host2Delete.Count==0)            {                MessageBox.Show("指定域名不存在!", "提示");                return;            }            StringBuilder sbConfirmMsg = new StringBuilder();            sbConfirmMsg.Append("以下域名将被删除:\n");            foreach (string host in host2Delete)            {                sbConfirmMsg.Append(host);                sbConfirmMsg.AppendLine();            }            if (MessageBox.Show(sbConfirmMsg.ToString(), "确认", MessageBoxButtons.OKCancel) != DialogResult.OK)            {                return;            }            using (StreamWriter sw = new StreamWriter(hostMappingFile))            {                sw.Write(sbFinalContent.ToString());            }            MessageBox.Show("删除成功!", "提示");        }        //添加新映射 throws Exception        private void AddNewHostMapping(string strDomain, string strIP, string strRemark)        {            //待写入文件的内容            StringBuilder sbFinalContent = new StringBuilder();            //读取系统原有映射(同时检验所添加的映射是否已存在)            if (File.Exists(hostMappingFile))            {                //有效映射行(行首到IP地址之间有0个以上空白字符,IP与域名间有1个以上空白字符,行末0个以上注释)                Regex regMapping = new Regex(@"^\s*\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s+" + strDomain + @"\s*(#.*)*$");                using (StreamReader sr = new StreamReader(hostMappingFile))                {                    string tmpLine = sr.ReadLine();                    while (tmpLine != null)                    {                        if (regMapping.IsMatch(tmpLine))                        {                            MessageBox.Show("域名已存在:\n" + tmpLine, "提示");                            return;                        }                        sbFinalContent.Append(tmpLine);                        sbFinalContent.AppendLine();                        tmpLine = sr.ReadLine();                    }                }            }            StringBuilder sbNewMapping = new StringBuilder();            sbNewMapping.Append(strIP.PadRight(15));//IP长度对齐,易读            sbNewMapping.Append(" ");            sbNewMapping.Append(strDomain);            sbNewMapping.Append("  #");            sbNewMapping.Append(strRemark);            sbNewMapping.Append(" added ");            sbNewMapping.Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));                        if (MessageBox.Show("添加域名:\n"+sbNewMapping.ToString(), "确认", MessageBoxButtons.OKCancel) != DialogResult.OK)            {                return;            }            //新映射            sbFinalContent.Append(sbNewMapping);            using (StreamWriter sw = new StreamWriter(hostMappingFile))            {                sw.Write(sbFinalContent.ToString());            }            MessageBox.Show("添加成功!", "提示");        }


【源代码可以在我的CSDN资源中下载 http://mengpanfei.download.csdn.net/】