实例介绍
【实例简介】
【实例截图】
【核心代码】
/*
* 网址:http://www.afuhao.com/article.aspx?articleId=84&articleGroupId=42
* 作者:符号
* Q Q:254186917
* 邮箱:service@afuhao.com
*
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Symbol.Net {
/// <summary>
/// hosts文件管理类,%windir%\system32\drivers\etc\hosts
/// </summary>
public static class HostsManager {
#region classes
/// <summary>
/// 行
/// </summary>
public class Line {
/// <summary>
/// 备注
/// </summary>
public string Comment { get; set; }
public override string ToString() {
return Comment;
}
}
/// <summary>
/// 主机映射
/// </summary>
public class HostLine : Line {
/// <summary>
/// IP地址
/// </summary>
public string IP { get; set; }
/// <summary>
/// 域名
/// </summary>
public string Domain { get; set; }
public override string ToString() {
//用Builder的原因是,String.Format 内部也是用的它
StringBuilder sb = new StringBuilder();
//IP和域名之间有空格的
sb.Append(IP).Append(' ').Append(Domain);
//没有备注,就不要多弄出一点东西来
if (!string.IsNullOrEmpty(Comment))
sb.Append(" #").Append(Comment);
return sb.ToString();
}
}
#endregion
/// <summary>
/// 由于这是系统唯一的一个文件,所以会用到锁,目的是保证同一时刻只有一个人在修改,以免改乱了
/// </summary>
private static readonly object _syncObject = new object();
private static readonly string _path;
/// <summary>
/// 用于匹配的正则表达式,以免每次都new,省事,另外兼容IPV6
/// </summary>
private static readonly System.Text.RegularExpressions.Regex _regex =
new System.Text.RegularExpressions.Regex(@"^\s*([\:0-9a-f\.] )\s ([a-zA-Z0-9_\-\.] )\s*[#]*(.*)$");
#region HostsManager
static HostsManager() {
//用statuc readonly 是为了不让内存回收把变量的值清掉了,在Web中经常要注意这个问题,不然你会死得很惨
//得到系统目录,貌似直接用%windir%也可以,为了安全起见,这里多做点事吧
_path= GetFolderPath(36);
//定位文件
_path = Path.Combine(_path, "system32\\drivers\\etc\\hosts");
}
//下面这个函数是从系统库中得来的,它不支持Windows这个选项,对应值是36,所以我改造了它,直接用数字了,在.NET 3.5是支持的。
[System.Security.SecuritySafeCritical]
public static string GetFolderPath(int folder) {
StringBuilder lpszPath = new StringBuilder(260);
Type type = Type.GetType("Microsoft.Win32.Win32Native, mscorlib");
int num = (int)type.InvokeMember("SHGetFolderPath", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod, null, null, new object[]{
IntPtr.Zero,(folder | 0), IntPtr.Zero, 0, lpszPath
});
if (num < 0) {
switch (num) {
case -2146233031:
throw new PlatformNotSupportedException();
}
}
string path = lpszPath.ToString();
return path;
}
#endregion
#region List
/// <summary>
/// 获取域名映射列表(如果有重复的映射,将不会去除重复。)
/// </summary>
/// <returns>返回域名映射列表</returns>
public static List<HostLine> List() {
lock (_syncObject) {
//先得到所有的行
List<Line> list = ListInternal();
List<HostLine> result = new List<HostLine>();
HostLine hostLine=null;
//过滤掉不是主机映射的行
foreach (Line line in list) {
hostLine = line as HostLine;
if (hostLine != null)
result.Add(hostLine);
}
list = null;
return result;
}
}
private static List<Line> ListInternal() {
List<Line> list = new List<Line>();
using (StreamReader reader = new StreamReader(_path,Encoding.Default)) {
string line = null;
System.Text.RegularExpressions.Match match = null;
bool normal = false;
while ((line = reader.ReadLine()) != null) {
normal = !string.IsNullOrEmpty(line);
//如果不是空行,看看是不是以#开头,因为这样就是整行为注释
if (normal && line.Trim().StartsWith("#"))
normal = false;
//如果正常,再检查一下是否是一行映射
if (normal)
normal = _regex.IsMatch(line);
if (normal) {
match = _regex.Match(line);
list.Add(new HostLine() {
IP = match.Groups[1].Value,
Domain = match.Groups[2].Value,
Comment = match.Groups[3].Value,
});
} else {
//这是一条普通行
list.Add(new Line() { Comment = line });
}
}
}
return list;
}
#endregion
#region Add
/// <summary>
/// 添加一个域名映射,如果存在同样的域名,自动替换旧的IP
/// </summary>
/// <param name="ip">需要绑定的IP</param>
/// <param name="domain">需要映射的域名</param>
public static void Add(string ip, string domain) {
Add(ip, domain, null);
}
/// <summary>
/// 添加一个域名映射,如果存在同样的域名,自动替换旧的IP
/// </summary>
/// <param name="ip">需要绑定的IP</param>
/// <param name="domain">需要映射的域名</param>
/// <param name="comment">备注信息</param>
public static void Add(string ip, string domain,string comment) {
if (string.IsNullOrEmpty(ip)) {
throw new ArgumentNullException("ip", "IP地址不能为空");
}
if (string.IsNullOrEmpty(domain)) {
throw new ArgumentNullException("domain", "域名不能为空");
}
lock (_syncObject) {
List<Line> list = ListInternal();
HostLine hostLine = null;
bool changed = false;
bool find = false;
foreach (Line line in list) {
hostLine = line as HostLine;
//如果不是行就跳过了
if (hostLine == null)
continue;
//如果域名匹配就处理,因为一个域名不能映射多个IP,要不然你访问哪一个IP呢?
if (hostLine.Domain.Equals(domain, StringComparison.OrdinalIgnoreCase)) {
find = true;//标记找到了
//如果IP不同就修改,这样以免多次写入文件,对系统不好
if (!hostLine.IP.Equals(ip)) {
hostLine.IP = ip;
changed = true;
}
//如果注释不一样也修改,
if (!string.Equals(hostLine.Comment, comment, StringComparison.OrdinalIgnoreCase)) {
hostLine.Comment = comment;
changed = true;
}
break;
}
}
//没找到就新加一条了
if (!find) {
list.Add(new HostLine() {
IP = ip,
Domain = domain,
Comment = comment,
});
changed = true;
}
//如果有修改就保存
if (changed)
Save(list);
}
}
#endregion
#region Save
private static void Save(List<Line> list) {
//if (File.Exists(_path)) {
// File.SetAttributes(_path, FileAttributes.Normal);
// File.Delete(_path);
//}
using (StreamWriter writer = new StreamWriter(_path, false, Encoding.Default)) {
//所有的都是行,所以一行一行的保存就行了,这里用了多态,每一行自己去处理如何输出
foreach (Line line in list) {
writer.WriteLine(line.ToString());
}
}
//string[] lines = new string[list.Count];
//for(int i=0;i<lines.Length;i ){
// lines[i] = list[i].ToString();
//}
//File.WriteAllLines(_path, lines, Encoding.Default);
}
#endregion
#region RemoveByIP
/// <summary>
/// 移除映射:通过IP地址
/// </summary>
/// <param name="ip">IP地址,只要匹配此IP映射都会被移除</param>
public static void RemoveByIP(string ip) {
if (string.IsNullOrEmpty(ip)) {
throw new ArgumentNullException("ip", "IP地址不能为空");
}
lock (_syncObject) {
List<Line> list = ListInternal();
HostLine hostLine = null;
//移除匹配的项,如果成功移除会返回条数,那么成功移除才保存
if (list.RemoveAll(line => {
hostLine = line as HostLine;
if (hostLine == null)
return false;
//必须是IP匹配的
return hostLine.IP.Equals(ip, StringComparison.OrdinalIgnoreCase);
}) > 0)
Save(list);
}
}
#endregion
#region RemoveByDomain
/// <summary>
/// 移除映射:通过域名
/// </summary>
/// <param name="domain">域名,匹配此域名的映射项都会被移除</param>
public static void RemoveByDomain(string domain) {
if (string.IsNullOrEmpty(domain)) {
throw new ArgumentNullException("domain", "域名不能为空");
}
lock (_syncObject) {
List<Line> list = ListInternal();
HostLine hostLine = null;
if (list.RemoveAll(line => {
hostLine = line as HostLine;
if (hostLine == null)
return false;
//必须是域名匹配的,不区分大小写
return hostLine.Domain.Equals(domain, StringComparison.OrdinalIgnoreCase);
}) > 0)
Save(list);
}
}
#endregion
}
}
好例子网口号:伸出你的我的手 — 分享!
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论