
暂无个人介绍
人工智能的最终达到实质的突破,是全部基础科学高度发展的基础上的,它最初的“生产应用”状态,如刚出生的孩子,需要通过学习,发挥出“人”与机器的双重优势。等发展到一定的程度,部分“代码”一样的物质将可以移植,它不等同于程序,程序不具有生命特征。 所 谓的智能,建立在类似人脑这样“联系”着的物质基础上,通过人脑类的作用机理(如经常性的联系,随着应用次数的增加,“道路”将扩大,而不经常用的联系将 逐渐的“消退”,但这种消退不是真的从“内存”中抹去,而是退一层,不在经常处理的任务中而模糊起来,从而为快速的处理提供层次架构方面的策略。等等,那 些人脑的最新前沿研究成果。这种模型随着人类的认识而逐渐增加新的“行为”方法,最终达到自主学习的状态。我本人的假设,如思维信号的“共振”模式处理复 杂的识别、处理和做出反应的步骤,从而为智能性的处理提供速度和多态性的结果),构建人工的智能机理模型。 人工智能的实质性突破,将引发最终的科技革命,他如同核子武器一样是把双刃剑,在更高级阶段,人类将无法对其控制。正如我的一个人无法控制另一个人的思想一样。 2013-04-01晚23:21 没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。 本文转自wenglabs博客园博客,原文链接:http://www.cnblogs.com/arxive/p/4688679.html,如需转载请自行联系原作者
转自原文 AE开发技术文档--8种数据访问方法 1、shapefileIWorkspaceFactory pWorkspaceFactory;pWorkspaceFactory = new ShapefileWorkspaceFactoryClass();IFeatureWorkspace pFeatWS;pFeatWS = pWorkspaceFactory.OpenFromFile(@"D:\Data", 0) as IFeatureWorkspace;//打开一个要素类IFeatureClass pFeatureClass = pFeatWS.OpenFeatureClass("Cities");2、coverageCoverage 是一个集合,它可以包含一个或多个要素类。Coverage 数据的工作空间也是它所在的文件夹;由于Coverage 可以包含多个要素类,得到工作空间后在打开具体的要素类时可以用“Coverage 名称:要素类名称”,例如下面代码中的“basin:polygon”。IWorkspaceFactory pFactory = new ArcInfoWorkspaceFactoryClass();IWorkspace pWorkspace = pFactory.OpenFromFile(@"D:\ArcTutor\TopologyData", 0);IFeatureWorkspace pFeatWorkspace = pWorkspace as IFeatureWorkspace;IFeatureClass pFeatureClass = pFeatWorkspace.OpenFeatureClass("basin:polygon");3、Geodatabase Personal Geodatabase 数据的工作空间指的是扩展名为mdb 的文件。以下是打开位于Monto.mdb 中的Water 要素类的代码。IWorkspaceFactory pFactory = new AccessWorkspaceFactoryClass();IWorkspace pWorkspace = pFactory.OpenFromFile(@"D:\ArcTutor\Monto.mdb", 0);IFeatureWorkspace pFeatWorkspace = pWorkspace as IFeatureWorkspace;IFeatureClass pFeatureClass = pFeatWorkspace.OpenFeatureClass("Water")4、ArcSDE(Enterprise Geodatabase)IWorkspaceFactory pWorkspaceFactory = new SdeWorkspaceFactoryClass();IPropertySet propSet = new PropertySetClass();propSet.SetProperty("SERVER", "actc");propSet.SetProperty("INSTANCE", "5151");propSet.SetProperty("USER", "apdm");propSet.SetProperty("ASSWORD", "apdm");propSet.SetProperty("VERSION", "SDE.DEFAULT");IWorkspace pWorkspace = pWorkspaceFactory.Open(propSet, 0);IFeatureWorkspace pFeatWS = pWorkspace as IFeatureWorkspace;IFeatureClass pFeatureClass= pFeatWS.OpenFeatureClass("ControlPoint");5、TinIWorkspaceFactory pWSFact = new TinWorkspaceFactoryClass();IWorkspace pWS = pWSFact.OpenFromFile(@"D:\ArcTutor\3DAnalyst", 0);ITinWorkspace pTinWS = pWS as ITinWorkspace;ITin pTin = pTinWS.OpenTin("mal");6、栅格数据IWorkspaceFactory rasterWorkspaceFactory = new RasterWorkspaceFactoryClass();IRasterWorkspace rasterWorkspace =rasterWorkspaceFactory.OpenFromFile(@"D:\data\grid", 0) as IRasterWorkspace;IRasterDataset rasterDataset= rasterWorkspace.OpenRasterDataset("ca_hillshade");7、CAD以下代码是打开位于D:\ArcTutor\Editor\ExerciseData\EditingFeatures 文件夹下的buildings.dxf 中的多边形要素类。IWorkspaceFactory pCadwf = new CadWorkspaceFactoryClass();IWorkspace pWS =pCadwf.OpenFromFile(@"D:\ArcTutor\Editor\ExerciseData\EditingFeatures", 0);IFeatureWorkspace pCadFWS = pWS as IFeatureWorkspace;IFeatureClass pFeatClass = pCadFWS.OpenFeatureClass("buildings.dxf:polygon");8、一般关系表//创建一个连接IPropertySet pPropset;pPropset = new PropertySetClass();pPropset.SetProperty("CONNECTSTRING",@"rovider=Microsoft.Jet.OLEDB.4.0;Data Source=E:\Company.mdbersist SecurityInfo=False");//创建一个新的OleDB工作空间并打开IWorkspaceFactory pWorkspaceFact;IFeatureWorkspace pFeatWorkspace;pWorkspaceFact = new OLEDBWorkspaceFactoryClass();pFeatWorkspace = pWorkspaceFact.Open(pPropset, 0) as IFeatureWorkspace;ITable pTTable = pFeatWorkspace.OpenTable("Custom"); 没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。 本文转自wenglabs博客园博客,原文链接:http://www.cnblogs.com/arxive/p/6110106.html,如需转载请自行联系原作者
1、线段绘制 基本步骤 构建形状 1. 创建 IPoint IPoint m_Point = new PointClass(); m_Point.PutCoords(x, y); 2. 创建 IPointCollection IPointCollection m_PointCollection = new PolylineClass(); m_PointCollection.AddPoint(m_Point, ref Type.Missing, ref Type.Missing); 3. 创建 IPolyline IPolyline m_Polyline = new PolylineClass(); m_Polyline = m_PointCollection as IPolyline; 4. 创建 IElement // Element 不能实例化,需要用其派生类实例化 IElement m_Element = m_SimpleLineSymbol as IElement; m_Element.Geometry = m_Polyline;设置形状样式 1. 创建 ISimpleLineSymbol ISimpleLineSymbol m_SimpleLineSymbol = new SimpleLineSymbolClass(); 2. 创建 ILineElement ILineElement m_LineElement = new LineElementClass(); m_LineElement.Symbol = m_SimpleLineSymbol;加载到地图 IMap m_Map = axMapControl1.Map; IActiveView m_ActiveView = m_Map as IActiveView; IGraphicsContainer m_Container = m_Map as IGraphicsContainer; m_Container.AddElement(m_Element, 0); m_Active.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null); ----------------------------------------------------------------------------------------------------------- 其他方法 View Code 2、编辑 点编辑: IPoint pt; pt = axMapControl1.ToMapPoint(e.x, e.y); IMarkerElement pMarkerElement; pMarkerElement = new MarkerElementClass(); IElement pElement; pElement = pMarkerElement as IElement; pElement.Geometry = pt; pGraphicsContainer = pMap as IGraphicsContainer; pGraphicsContainer.AddElement((IElement)pMarkerElement, 0); pActiveView.Refresh(); 线编辑: 1 2 3 4 5 6 7 8 9 10 IGeometry polyline; polyline = axMapControl1.TrackLine(); ILineElement pLineElement; pLineElement = new LineElementClass(); IElement pElement; pElement = pLineElement as IElement; pElement.Geometry = polyline; pGraphicsContainer = pMap as IGraphicsContainer; pGraphicsContainer.AddElement((IElement)pLineElement, 0); pActiveView.Refresh(); 面编辑: 1 2 3 4 5 6 7 8 9 10 IGeometry Polygon; Polygon = axMapControl1.TrackPolygon(); IPolygonElement PolygonElement; PolygonElement = new PolygonElementClass(); IElement pElement; pElement = PolygonElement as IElement; pElement.Geometry = Polygon; pGraphicsContainer = pMap as IGraphicsContainer; pGraphicsContainer.AddElement((IElement)PolygonElement, 0); pActiveView.Refresh(); ArcEngine中画shape点的另一种方法 public override void OnMouseDown(int Button, int Shift, int X, int Y) { //base.OnMouseDown(Button, Shift, X, Y); IFeatureLayer pFeatureLayer = mapControl.Map.get_Layer(0) as IFeatureLayer; IFeatureClass fc = pFeatureLayer.FeatureClass; IFeatureClassWrite fr = fc as IFeatureClassWrite; IWorkspaceEdit pWorkspaceEdit = (fc as IDataset).Workspace as IWorkspaceEdit; IFeature pFeature; IPoint pPoint; //开始事物操作 pWorkspaceEdit.StartEditing(false); //开始编辑 pWorkspaceEdit.StartEditOperation(); pFeature = fc.CreateFeature(); pPoint = new PointClass(); IPoint Mp = mapControl.ToMapPoint(X, Y); pPoint.PutCoords(Mp.X, Mp.Y); pPoint.SpatialReference = mapControl.SpatialReference; pFeature.Shape = pPoint; pFeature.Store(); mapControl.ActiveView.Refresh(); if (Button == 2) { pWorkspaceEdit.StopEditOperation(); pWorkspaceEdit.StopEditing(true); } } 3、绘制Element、Symbol 在控件上 做符号预览的时候需要将ISymbol或IElement绘制到指定的控件上,下面边码边说,一起讨论讨论: 3.1 绘制在Panel上 ISymbol接口有Draw函数,查询其接口可以发现,我们需要执行ISymbol.SetupDC -> ISymbol.Draw -> ISymbol.ResetDC 这三个步骤; 首先SetupDC需要参数 hDC和IDisplayTransformation;贴代码: 例如:绘制在Panel上: int width=Panel.Width; int heigth=Panel.Heigth; //绘制方法 Graphics graph=Graphics.FromHwnd(Panel.Handle); graph.Clear(Panel.BackColor); //分辨率 double dpi=graph.DpiX; IEnvelope pEnve=new EnvelopeClass(); pEnve.PutCoords(0,0,width,heigth); Ipoint pCenterPt=new PointClass; pCenter.PutCoords(width/2,height/2); tagRECT myRect=new tagRECT(); 设置MyRect 的 top=0;bottom=heigh; left=0,right=width; IDisplayransformation pDisTrans=new DisplayTrabsformation(); pDisTrans.VisiableBounds=pEnve; pDisTrans.Bounds=pEnv; pDisTrans.Set_DeviceFrame(ref myRect); pDisTrans.Resolution=dpi; intPtr hdc=graph.GetHdc(); ISymbol.SetupDC(hec.ToInt32,pDisTrans); ISymbol.Draw(pCenterPt); ISymbol.ResetDC(); //绘制完成后 是否绘图对象 graph.ReleaseHdc(hdc); graph.Dispose(); Symbol的第二种方法 IStyleGalleryItem item=new ServerStyleGalleryItemClass(); item.Item=youSymbol;//你需要预览的ISymbol stdole.IPictureDisp pic=axSymbologyControl1.GetStyleClass(esriSymbologyStyleClass).PriviewItem(item,100,100); Image img=Image.FormHbitmap(new IntPtr(pic.Handle)); picPriview.Image=img; 3.2 绘制Element 在Panel控件上 其中 graph、pCenterPoint、pDisTrans 的设置方式和上面一样 以绘制线段为例: IDisplay pDisplay=new SimpleDisplay(); pDisplay.StartDrawing(graph.GetHdc(),ToInt32(),(short)esriScreeCache.esriNoScreeCache); pDisplay.DisplayTransformation=pDisTrans; pDisplay.SetSymbol(LineSymbol);//设置绘制线段的符号 pDisplay.DrawPolyline(IGeometry) ;//设置绘制线段的几何数据 //在arcgis帮助中找吧 参考文章 ArcGIS Engine 线段绘制研究 ArcEngine画shapefile点,线,面 ArcEngine中画shape点的另一种方法 Arcengine 绘制Element、Symbol 在控件上 没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。 本文转自wenglabs博客园博客,原文链接:http://www.cnblogs.com/arxive/p/8145435.html,如需转载请自行联系原作者
AJax几乎成了web2.0的一个代表,Java和Asp.net中都提供了一些AJax操作的控件。在MonoRail中也同样提供了AJax操作的共通类:AJaxHelperAJaxHelper可以指定当文本框输入变化时调用后台代码、可以监控一个Form,当Form内控件值变化时调用后台代码、可以在点击一个按钮时调用后台代码,也可以在页面加载时就调用后台代码。当然这些调用都是采用AJax,即无刷新方式的,调用后可以自动更新页面中的一块区域的内容。使用AJaxHelper后,几乎只要处理自己的业务逻辑就可以了,和AJax有关的代码都封装好了。下面就来看看这几种方式的使用方法:以下的Controller类都是从SmartDispatcherController继承的一、监控文本框Controller代码: public void index() { } public void InferAddress(String zip) { RenderText("Address " + zip); } 其中String zip的zip变量名需要和vm页面中的控件名相同 vm代码: 1<html> 2<head> 3$AjaxHelper.GetJavascriptFunctions() 4</head> 5 6<body> 7<form id="theform"> 8 请输入邮政号码:<br> 9 <input type="text" name="zip" id="zip"> 10 <br>11 <div id="address">12 </div>13</form>1415$AjaxHelper.ObserveField("%{field='zip', frequency='2', url='inferaddress.rails', update='address', with='Form.serialize(theform)'}")1617</body>18</html>19 第三行是注册AJax的脚本,第十五行就是监听zip控件,当输入变化时自动调用inferaddress.rails,将返回的文本更新到dir id="address"的区域中二、监控Formvm: <html><head>$AjaxHelper.GetJavascriptFunctions()</head><body><form id="myform"> 姓名: <input type="text" name="name" id="name"> <br> 地址: <input type="text" name="addressf" id="addressf"> <br> <div id="message"> </div></form>$AjaxHelper.ObserveForm("myform", 2, "FormTest.rails", "message", null)</body></html> controller public void FormTest(string value, string addressf) { RenderText(value + "::" + addressf); } 这里的定义有点奇怪,好像是一个BUG,也可能是1.0 RC3还在开发阶段所致 对Form中的第一个控件:"姓名",在controller必须定义成"value"名才能取得值,而且取得的值也有问题(会在前面加上控件名称),看下面的执行结果:三、响应按钮事件vm: <html><head>$AjaxHelper.GetJavascriptFunctions()</head><body> <div id="userlist"> </div> $AjaxHelper.BuildFormRemoteTag("UserList.rails", "%{update='userlist'}" )<table> <tr> <td>姓名:</td> <td><input type="text" name="name"></td> </tr> <tr> <td>邮件:</td> <td><input type="text" name="email"></td> </tr> <tr> <td colspan="2" align="center"> <input type="submit" value="增加"> </td> </tr></table> </form></body></html> controller: public void UserList(String name, String email) { IList list = Session["userlist"] as IList; if (list == null) { list = new ArrayList(); } list.Add(name + " " + email + "<br>"); Session["userlist"] = list; System.Text.StringBuilder userList = new System.Text.StringBuilder(); for (int i = 0; i < list.Count; i++) { userList.Append(list[i] as string); } RenderText(userList.ToString()); } 这样每次点增加按钮时,就可以不用刷新页面,直接就能把增加的信息显示在指定的位置了,当然你可以执行一些复杂的操作四、直接调用后台代码Controller public void User() { RenderText("user :" + Session["name"] as string); } vm: $AjaxHelper.GetJavascriptFunctions() <div id="user"> </div> <script language=javascript> new Ajax.Updater('user', '/myajax/User.rails', {}); </script> 可以在页面加载时就调用指定的User.rails命令,更新user区域 本文转自永春博客园博客,原文链接:http://www.cnblogs.com/firstyi/archive/2007/11/05/950026.html,如需转载请自行联系原作者
Oracle Berkeley DB 11gR2于2010年3月23日发布,首次引入SQL支持,完全兼容SQLite的SQL API。 SQLite程序可以无缝移植到BDB上。 使用Oracle Berkeley DB可以有SQL, Key/Value, XML/XQuery or Java Object storage 等多种选择。 不仅仅是SQL. 而且支持Windows Mobile,Windows Embedded CE,Android等移动设备。 相关链接: http://www.oracle.com/database/berkeley-db/index.html 以前一些关于SQLite的文章: Windows Mobile下访问Sqlite的Native C++封装 如何压缩SQLite的数据文件 本文转自Jake Lin博客园博客,原文链接:http://www.cnblogs.com/procoder/archive/2010/03/25/Oracle_Berkeley_DB_SQLite.html,如需转载请自行联系原作者
PDF.NET 开发框架之 SOD框架 Ver 5.2.1.0307 正式版发布,包含以下部分: SOD_Pwmis.Core --包括下列数据提供程序 SqlServer SqlServerCe Access OleDb ODBC Oracle --包含框架的核心类库 PDF.NET SOD All --包括框架的全部类库和数据提供程序,目前有 SQLite MySQL PostgreSQL PDF.NET SOD AllSource --包括全部类库源码和示例程序源码,包括超市管理系统源码 PDF.NET SOD 文档 --包括下列文档: _NET ORM 的 “SOD蜜”--零基础入门篇 - 深蓝医生 - 博客园 PDF_NET SOD 开源框架红包派送活动 && 新手快速入门指引 - 深蓝医生 - 博客园 PDF实体类效率测试 PWMIS.Core.chm 版本说明 解决方案说明 -------------------------------------分界线-------------------------------- SOD : one SQL-MAP,ORM,Data Control framework SOD框架是PDF.NET 开发框架的子集,如下图: 有关详细内容,请参见框架官网 http://www.pwmis.com/sqlMap/ 有关开源的最新信息,请参见框架开源项目网站 http://pwmis.codeplex.com/ 本文转自深蓝医生博客园博客,原文链接:http://www.cnblogs.com/bluedoctor/p/4321218.html,如需转载请自行联系原作者
文回顾 前面的三篇文章,我把AgileEAS.NET平台的UDA的应用案例从数据处理方式与流程、基础的语句执行、查询处理以及引入的委托处理机制、事务的两种处理方法,基本上涵盖了基于数据支撑的业务信息系统所涉及的所有数据库处理。 存在的问题 前三篇文章中所涉及的例程代码中,对于数据库连接环境程序中定义了一个单例模式工的类UdaContext: 1 /// <summary> 2 /// 数据上下文辅助类(不用了)。 3 /// </summary> 4 class UdaContext2 5 { 6 #region 单例模型 7 8 /// <summary> 9 /// 内部私有成员,UdaContext对象的唯一实例。10 /// </summary>11 protected static UdaContext2 instance;12 private static readonly object _lock = new object();13 14 /// <summary>15 /// 初始化 UdaContext 对象实例。16 /// </summary>17 UdaContext2()18 {19 20 }21 22 /// <summary>23 /// ClassProvider对象的唯一实例。24 /// </summary>25 static UdaContext2 Instance26 {27 get28 {29 if (instance == null)30 {31 lock (_lock)32 {33 if (instance == null)34 instance = new UdaContext2();35 }36 }37 38 return instance;39 }40 }41 42 #endregion43 44 IDataConnection dataConnection = null;45 IDataAccessor dataAccessor = null;46 47 /// <summary>48 /// IDataConnection比IConnection更加抽像一些。49 /// </summary>50 /// <remarks>51 /// IDataConnection不能支持标准方式的事务,只支持事务代理。52 /// </remarks>53 public static IConnection Connection54 {55 get56 {57 return DataConnection as IConnection;58 }59 } 60 61 public static IDataConnection DataConnection62 {63 get64 {65 if(Instance.dataConnection==null)66 Instance.dataConnection = new OleDbConnection("Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Password=;Initial Catalog=eas;Data Source=vm2003");67 68 return Instance.dataConnection;69 }70 }71 72 public static IDataAccessor DataAccessor73 {74 get75 {76 if (Instance.dataAccessor == null)77 Instance.dataAccessor = DataConnection.CreateDataAccessor();78 79 return Instance.dataAccessor;80 }81 } 82 } 各示例方法中使用数据操作对象都是通过IDataAccessor accessor = UdaContext.DataAccessor这样的方法事获取数据操纵对象,遥IDataAccessor 又依附于对象IDataConnection之上,在UdaContext类中完成了数据连接环境的实现化: if(Instance.dataConnection==null) Instance.dataConnection = new OleDbConnection("Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Password=;Initial Catalog=eas;Data Source=vm2003"); 上迷代码实例化了OleDbConnection方式的数据连接环境,平台中提供了OleDbConnection、SqlClientConnection、ODBCConnection连接,当然也实现了独立的Oracle Connection,也就是说应用程序中存在着数据连接的实例化过程,这种方式是有一些问题的。 使用IOC进行解偶 既然我们发现了问题,那我们就来解决问题吧,如何解决呢,解决的方案有很多,可以通过抽像工厂模式或者使用其他的N种方式,我就不一一来说了,我推荐使用AgileEAS.NET平台的控制反转(IOC)组件来完成这部分解决,有关AgileEAS.NET平台IOC组件的介绍请参见AgileEAS.NET平台之对象控制反转一文。 现在我们来改造我们的UdaContext如下: 1 /// <summary> 2 /// 辅助类。 3 /// </summary> 4 static class UdaContext 5 { 6 /// <summary> 7 /// IDataConnection比IConnection更加抽像一些。 8 /// </summary> 9 /// <remarks>10 /// IDataConnection不能支持标准方式的事务,只支持事务代理。11 /// </remarks>12 public static IConnection Connection13 {14 get15 {16 return DataConnection as IConnection;17 }18 } 19 20 public static IDataConnection DataConnection21 {22 get23 {24 return DataAccessor.DataConnection;25 }26 }27 28 public static IDataAccessor DataAccessor29 {30 get31 {32 return ContextHelper.GetContext().Container.GetComponentInstance("DataAccessor") as IDataAccessor;33 }34 } 35 } 这里面关键的是这一句ContextHelper.GetContext().Container.GetComponentInstance("DataAccessor") as IDataAccessor,实现从容器中取出名称为DataAccessor的组件,并完成其他属性与构造注入。 接下来,我们为这个控制台程序增加一个应用程序配置文件并写如以下内容: 1 <?xml version="1.0" encoding="utf-8"?> 2 <configuration> 3 <configSections> 4 <section name="EAS.Objects" type="EAS.Objects.ConfigHandler,EAS.IOCContainer"/> 5 </configSections> 6 <EAS.Objects> 7 <object name="DataConnection" assembly="EAS.Data" type="EAS.Data.Access.SqlClientConnection" LifestyleType="Singleton"> 8 <property name="ConnectionString" type="string" value="Data Source=vm2003;Initial Catalog=eas;User ID=sa" /> 9 </object>10 <object name="DataAccessor" assembly="EAS.Data" type="EAS.Data.Access.SqlClientAccessor" LifestyleType="Singleton">11 <property name="Connection" type="object" value="DataConnection" />12 </object>13 </EAS.Objects>14 </configuration> 编译程序,运行输出如下结果: 到此为止,有关于AgileEAS.NET平台中的统一数据访问(UDA)组件的案例 示例到此结束,接下来我们开始ORM组件的案案讲解。 有关本例子所涉及的数据表结构请参考基于AgileEAS.NET平台基础类库进行应用开发-总 体说明及数据定义一文,有关数据对象模型定义文件、文档、DDL脚本请下载:http://files.cnblogs.com/eastjade/demo.db.doc.sql.rar,本文代码下载:UDA.Demo4.rar。 链接 AgileEAS.NET平台开发指南-系列目录 AgileEAS.NET应用开发平台介绍-文章索引 一步一步教你使用AgileEAS.NET基础类库进行应用开发-系列目录 AgileEAS.NET平台应用开发教程-案例计划 AgileEAS.NET官方网站 敏捷软件工程实验室 QQ群:116773358 作者:魏琼东 出处:http://www.cnblogs.com/eastjade关于作者:有13年的软件从业经历,专注于中小软件企业软件开发过程研究,通过在技术与管理帮助中小软件企业实现技术层面开源节流的目的。熟悉需求分析、企业架构、项目管理。现主要从事基于AgileEAS.NET平台的技术咨询工作,主要服务于医疗卫生、铁路、电信、物流、物联网、制造、零售等行业。如有问题或建议,请多多赐教! 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过mail.james@qq.com 联系我,也可以加入QQ群:113723486、199463175、116773358、116773358、212867943、147168308、59827496、193486983、15118502和大家共同讨论,非常感谢。 本文转自魏琼东博客园博客,原文链接:,如需转载请自行联系原作者
在“文本比较算法Ⅰ——LD算法”中,介绍了编辑距离的计算。 在“文本比较算法Ⅱ——Needleman/Wunsch算法”中,介绍了最长公共子串的计算。 在给定的字符串A和字符串B,LD(A,B)表示编辑距离,LCS(A,B)表示最长公共子串的长度。 如何来度量它们之间的相似度呢? 不妨设S(A,B)来表示字符串A和字符串B的相似度。那么,比较合理的相似度应该满足下列性质。 性质一:0≤S(A,B)≤100%,0表示完全不相似,100%表示完全相等 性质二:S(A,B)=S(B,A) 目前,网上介绍的各种相似度的计算,都有各自的不尽合理的地方。 计算公式一:S(A,B)=1/(LD(A,B)+1) 能完美的满足性质二。 当LD(A,B)=0时,S(A,B)=100%,不过无论LD(A,B)取任何值,S(A,B)>0,不能满足性质一。 计算公式二:S(A,B)=1-LD(A,B)/Len(A) 当Len(B)>Len(A)时,S(A,B)<0。不满足性质一。 有人会说,当S(A,B)<0时,强制指定S(A,B)=0就解决问题了。 问题是,S(A,B)=1-LD(A,B)/Len(A),而S(B,A)=1-LD(B,A)/Len(B)。当Len(A)≠Len(B)时,S(A,B)≠S(B,A)。不满足性质二 还有一个例子可以说明问题 A="BC",B="CD",C="EF" S(A,B)=1-LD(A,B)/Len(A)=1-2/2=0 S(A,C)=1-LD(A,C)/Len(A)=1-2/2=0 A和B的相似度与A和C的相似度是一样的。不过很明显的是B比C更接近A 计算公式三:S(A,B)=LCS(A,B)/Len(A) 这个公式能完美的满足的性质一 不过当Len(A)≠Len(B)时,S(A,B)≠S(B,A)。不满足性质二 用一个例子说明问题 A="BC",B="BCD",C="BCEF" S(A,B)=LCS(A,B)/Len(A)=2/2=100% S(A,C)=LCS(A,C)/Len(A)=2/2=100% A和B的相似度与A和C的相似度是一样的。不过很明显的是B比C更接近A 上面是网上能找到的三个计算公式,从上面的分析来看都有各自的局限性。 我们看一个例子: A=GGATCGA,B=GAATTCAGTTA,LD(A,B)=5,LCS(A,B)=6 他们的匹配为: A:GGA_TC_G__A B:GAATTCAGTTA 可以看出上面蓝色的部分表示的是LCS部分,黑色表示的是LD部分。 因此,给出一个新的公式 S(A,B)=LCS(A,B)/(LD(A,B)+LCS(A,B)) 这个公式能解决上述三个公式的种种不足。 而LD(A,B)+LCS(A,B)表示两个字符串A、B的最佳匹配字串的长度。这个是唯一的。 还有注意的是LD(A,B)+LCS(A,B)和Max(Len(A),Len(B))这两个并不完全相等。 本文转自万仓一黍博客园博客,原文链接:http://www.cnblogs.com/grenet/archive/2010/06/04/1751147.html,如需转载请自行联系原作者
随着高速(20M)宽带、HTPC、大容量硬盘(3T)的普及,下载高清片并利用大屏幕观看也成为普通的事情。 随着下载影片的增多,管理就有了问题,有时在茫茫文件夹下找寻一个影片也是一件费时费力的事。 于是萌生了自己编写电影管理器的想法,并逐步逐步在实现。利用博客记录编写的过程,也是和网友之间的交流。期望在交流的过程中,网友能提出一些中肯的意见,使自己少走些弯路。 我在拿到一个高清视频文件时。我希望能有办法获知以下的信息 文件名:视频文件的文件名,这个比较简单,利用FileInfo类就能获得 文件大小:视频文件的大小,这个也比较简单,利用FileInfo类能获得 视频分辨率:视频文件的分辨率,例如:宽1980像素,高1040像素。 视频时长:视频文件的时长,例如:长1小时32分 音频数:视频文件中的音频数,有不少的高清视频文件中包含不止一个音频。有的包含英文、中文2个音频;有的包含英文、中文、粤语3个音频 音频的语言类型:具体到每个音频的语言。例如:音频1是英文,音频2是中文等 以上信息中的后面四个(视频分辨率、视频时长、音频数、音频的语言类型),用视频播放器都能获得。但是如何在自己的程序中获得这些信息呢? 我们可以利用MediaInfo来获取这些信息(视频分辨率、视频时长、音频数、音频的语言类型) 先看看MediaInfo的介绍,MediaInfo官网。在官网上有相关的介绍,并给出了调用的代码(很完备。C++,C#,Visual Basic等都有) 高清视频文件的相关信息都保存在文件的头部区域,记录的信息有很多(除却上面的四种外,还包括码率、编码类型等等)。而MediaInfo就是利用读取头部区域的信息来获得相关的信息。官网的更新很快,笔者下载的是2013年7月6日发布的最新版。 下面就介绍如何利用MediaInfo来获得高清视频文件的相关信息。 1、下载相应的DLL 在http://sourceforge.net/projects/mediainfo/files/development_snapshots/上点击Download MediaInfo_GUI_0.7.64_Windows.exe (4.5 MB),下载最新的版本。安装后在安装的目录中找到MediaInfo.dll和MediaInfo_i386.dll这两个DLL文件。 2、新建项目 在VS2010中新建项目,把相关的DLL复制到可执行程序的目录(在项目文件夹下的bin\Debug\,或者复制到系统目录中) 注:MediaInfo.dll貌似是64位的;MediaInfo_i386.dll貌似是32位的;在后面的调试中,MediaInfo.dll始终会报错,反而MediaInfo_i386.dll改成MediaInfo.dll后复制到目录中调试一遍成功。 3、把官网中的提供的调用代码添加到项目中来 由于DLL仅仅提供了函数。而目前的编码基本上都是面向对象,所以在官网上针对很多的语言都提供了相应的代码,把函数调用包装成类,方便调用者使用。Visual Basic的调用代码在http://sourceforge.net/p/mediainfo/code/5846/tree/MediaInfoLib/trunk/Project/MSVB2010/上,其他语言在相关的网页上也能找到,这里就不赘述了。 要注意的是,在如上所做时,还得在VS2010中进行设置 在打开的项目属性中,点开“调试”,勾上“启用非托管代码调试”,才能正常调试。 如果没有勾上,运行时则会出现下面的对话框 可能是缺少Lib文件的缘故,不过我没在官网上找到Lib文件的下载 另,不需要在项目中对MediaInfo.dll引用。引用会出错,如下所示: 官网上的Visual Basic 2010调用代码如下: Imports System.Runtime.InteropServices Public Enum StreamKind As UInteger General Visual Audio Text Chapters Image Menu Max End Enum Public Enum InfoKind As UInteger Name Text Measure Options NameText MeasureText Info HowTo Max End Enum Public Enum InfoOptions As UInteger ShowInInform Reserved ShowInSupported TypeOfValue Max End Enum Public Class MediaInfo Private Declare Unicode Function MediaInfo_New Lib "MediaInfo.DLL" () As IntPtr Private Declare Unicode Sub MediaInfo_Delete Lib "MediaInfo.DLL" (ByVal Handle As IntPtr) Private Declare Unicode Function MediaInfo_Open Lib "MediaInfo.DLL" (ByVal Handle As IntPtr, ByVal FileName As String) As UIntPtr Private Declare Unicode Sub MediaInfo_Close Lib "MediaInfo.DLL" (ByVal Handle As IntPtr) Private Declare Unicode Function MediaInfo_Inform Lib "MediaInfo.DLL" (ByVal Handle As IntPtr, ByVal Reserved As UIntPtr) As IntPtr Private Declare Unicode Function MediaInfo_GetI Lib "MediaInfo.DLL" (ByVal Handle As IntPtr, ByVal StreamKind As UIntPtr, ByVal StreamNumber As UIntPtr, ByVal Parameter As UIntPtr, ByVal KindOfInfo As UIntPtr) As IntPtr Private Declare Unicode Function MediaInfo_Get Lib "MediaInfo.DLL" (ByVal Handle As IntPtr, ByVal StreamKind As UIntPtr, ByVal StreamNumber As UIntPtr, ByVal Parameter As String, ByVal KindOfInfo As UIntPtr, ByVal KindOfSearch As UIntPtr) As IntPtr Private Declare Unicode Function MediaInfo_Option Lib "MediaInfo.DLL" (ByVal Handle As IntPtr, ByVal Option_ As String, ByVal Value As String) As IntPtr Private Declare Unicode Function MediaInfo_State_Get Lib "MediaInfo.DLL" (ByVal Handle As IntPtr) As UIntPtr Private Declare Unicode Function MediaInfo_Count_Get Lib "MediaInfo.DLL" (ByVal Handle As IntPtr, ByVal StreamKind As UIntPtr, ByVal StreamNumber As IntPtr) As UIntPtr Dim Handle As IntPtr Sub New() Handle = MediaInfo_New() End Sub Protected Overrides Sub Finalize() MediaInfo_Delete(Handle) End Sub Function Open(ByVal FileName As String) As System.UIntPtr Return MediaInfo_Open(Handle, FileName) End Function Sub Close() MediaInfo_Close(Handle) End Sub Function Inform() As String Return Marshal.PtrToStringUni(MediaInfo_Inform(Handle, CType(0, UIntPtr))) End Function Function Get_(ByVal StreamKind As StreamKind, ByVal StreamNumber As Integer, ByVal Parameter As Integer, Optional ByVal KindOfInfo As InfoKind = InfoKind.Text) As String Return Marshal.PtrToStringUni(MediaInfo_GetI(Handle, CType(StreamKind, UIntPtr), CType(StreamNumber, UIntPtr), CType(Parameter, UIntPtr), CType(KindOfInfo, UIntPtr))) End Function Function Get_(ByVal StreamKind As StreamKind, ByVal StreamNumber As Integer, ByVal Parameter As String, Optional ByVal KindOfInfo As InfoKind = InfoKind.Text, Optional ByVal KindOfSearch As InfoKind = InfoKind.Name) As String Return Marshal.PtrToStringUni(MediaInfo_Get(Handle, CType(StreamKind, UIntPtr), CType(StreamNumber, UIntPtr), Parameter, CType(KindOfInfo, UIntPtr), CType(KindOfSearch, UIntPtr))) End Function Function Option_(ByVal Option__ As String, Optional ByVal Value As String = "") As String Return Marshal.PtrToStringUni(MediaInfo_Option(Handle, Option__, Value)) End Function Function State_Get() As Integer Return CInt(MediaInfo_State_Get(Handle)) End Function Function Count_Get(ByVal StreamKind As StreamKind, Optional ByVal StreamNumber As UInteger = UInteger.MaxValue) As Integer If StreamNumber = UInteger.MaxValue Then Return CInt(MediaInfo_Count_Get(Handle, CType(StreamKind, UIntPtr), CType(-1, IntPtr))) Else Return CInt(MediaInfo_Count_Get(Handle, CType(StreamKind, UIntPtr), CType(StreamNumber, IntPtr))) End If End Function End Class 4、再次包装,方便调用 由于上面的代码是提供了一个类供调用者使用,因此,我决定再包装一下,使其看起来简单一些(我只需要分辨率、时长、音频数、音频语言这四个信息)。 我包装的代码如下: Public Class clsMediaInfo Private _M As MediaInfo Public Sub New() _M = New MediaInfo End Sub Public Function GetInfo(FileName As String) As String _M.Open(FileName) _M.Option_("Complete") Return _M.Inform End Function Public Function Width() As String Return _M.Get_(StreamKind.Visual, 0, "Width") End Function Public Function Height() As String Return _M.Get_(StreamKind.Visual, 0, "Height") End Function Public Function Duration() As String Return _M.Get_(StreamKind.General, 0, "Duration/String3") End Function Public Function AudioCount() As Integer Return Convert.ToInt32(_M.Get_(StreamKind.General, 0, "AudioCount")) End Function Public Function AudioLanguage(Index As Integer) As String If Index < 0 OrElse Index > AudioCount() - 1 Then Index = 0 Return _M.Get_(StreamKind.Audio, Index, "Language/String") End Function Public Function AudioLanguage() As String() Dim I As Integer, C As Integer = AudioCount() Dim L(C - 1) As String For I = 0 To C - 1 L(I) = _M.Get_(StreamKind.Audio, I, "Language/String") Next Return L End Function End Class 解释一下: 首先在类的内部定义一个MediaInfo类的实例,具体的功能都是通过该实例来完成。 在查看信息前,需调用GetInfo(FileName As String)函数,该函数的目的是获得相关的信息,一共三句话 _M.Open(FileName) _M.Option_("Complete") Return _M.Inform 第1句,打开FileName指定的文件;第2句,获取相关信息,并通知类,已经获取完毕(可能在DLL中会有释放资源等操作);第3句,返回视频文件的相关信息。 第3句话返回的是所有的信息,长长的一串。 如果仅仅是想获得某一个信息,则需要调用下面的语句 _M.Get_(StreamKind.Visual, 0, "Width") 一共三个参数。 第1个参数,获取信息的类别。一般取StreamKind.General(通用信息)、StreamKind.Visual(视频信息)、StreamKind.Audio(音频信息) 第2个参数,获取信息的流编号。一般取0(第1个流,视频一般就1个流,音频有可能多于1个流),音频的话,取相应的流编号(0开始,到流数减1) 第3个参数,获取信息的名字。根据该参数返回对应的信息。 那么,对应的调用就是 视频宽度:_M.Get_(StreamKind.Visual, 0, "Width") 视频高度:_M.Get_(StreamKind.Visual, 0, "Height") 视频时长:_M.Get_(StreamKind.General, 0, "Duration/String3")。这个有多种选择,该调用返回 01:34:48.683 这种格式;如果是:_M.Get_(StreamKind.General, 0, "Duration"),则返回 5688683 ,还需要自己转换。 音频个数:_M.Get_(StreamKind.General, 0, "AudioCount") 音频语言:_M.Get_(StreamKind.Audio, I, "Language/String")。也是多种选择,该调用返回 English 这种格式;如果是:_M.Get_(StreamKind.Audio, I, "Language"),则返回 en 这种格式。 如果想获取其他的信息,直接给出相应的参数就行了。例如想获得视频的最大码率,给出参数BitRate_Maximum就行了。如下调用 _M.Get_(StreamKind.Visual, 0, "BitRate_Maximum") 那么,如何能知道有哪些参数呢?参看 MediaInfo参数大全 C#使用MediaInfo查看媒体信息 这两篇文章对参数介绍的很详细,只是文章写得早,提供的DLL版本比较低罢了 下面是获取 G:\Despicable.Me.2010.BluRay.1080p.DTS.2Audio.x264-CHD.mkv 这个高清视频文件信息的调用代码: Dim S As New clsMediaInfo S.GetInfo("G:\Despicable.Me.2010.BluRay.1080p.DTS.2Audio.x264-CHD.mkv") Dim S1 As String = "" S1 &= S.Width & " " & S.Height & vbNewLine S1 &= S.Duration & vbNewLine S1 &= S.AudioCount & vbNewLine S1 &= S.AudioLanguage(0) & "," & S.AudioLanguage(1) RichTextBox1.Text = S1 返回的信息如下: 1920 1040 01:34:48.683 2 English,Chinese 说明视频分辨率为1920*1040;时长:1小时34分48秒;2个音频;分别是英文和中文; 这个代码在做高清视频文件的信息库的时候特别有用。可以根据高清视频文件自动获取相关信息,毋须再手动填充信息。 本文转自万仓一黍博客园博客,原文链接:http://www.cnblogs.com/grenet/p/3222731.html,如需转载请自行联系原作者
在Silverlight 5 RC版本中新增了对并行任务库(Task Parallel Library)的支持,Task Parallel Library简称TPL,它是指一个或者多个任务同时运行,类似线程或者线程池。在本例中将会以并行任务库和异步获取数据进行对比。相关资料可以看http://msdn.microsoft.com/en-us/library/dd537609.aspx和http://www.cnblogs.com/vwxyzh/tag/TPL/ 首先新建一个Silverlight 5项目,在其Web项目中添加一个新的xml文件helloWorld.xml。编写代码如下: <?xml version="1.0" encoding="utf-8" ?> <a>111</a> 然后我们看Silverlight 4及之前的版本中如何异步获取数据,其代码如下: //SL4异步获取结果 private void SL4InitiateWebRequest() { HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://localhost:12887/helloWorld.xml"); request.BeginGetResponse(new AsyncCallback(onRequestComplete), request); }private void onRequestComplete(IAsyncResult asynchronousResult) { HttpWebRequest request = asynchronousResult.AsyncState as HttpWebRequest; HttpWebResponse response = request.EndGetResponse(asynchronousResult) as HttpWebResponse;var s = response.GetResponseStream();var reader = new StreamReader(s);string xmlFileText = reader.ReadToEnd();this.Dispatcher.BeginInvoke(() => { MessageBox.Show("这是SL4获取Xml数据:"+xmlFileText); }); } 然后我们再看通过TPL来异步获取数据,当然这之前需要using System.Threading.Tasks。 //silverlight 5并行计算 private void SL5InitiateWebRequest() {string uri = "http://localhost:12887/helloWorld.xml";var request = HttpWebRequest.Create(uri); var webTask = Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse,TaskCreationOptions.None) .ContinueWith(task => { var response = (HttpWebResponse)task.Result; var stream = response.GetResponseStream();var reader = new StreamReader(stream); string xmlFileText = reader.ReadToEnd();this.Dispatcher.BeginInvoke(() => { MessageBox.Show("这是SL5获取Xml的数据:" + xmlFileText); }); }); } 最后我们客户端调用上面的两种方式来获取数据。 public MainPage() { InitializeComponent();//调用普通异步 SL4InitiateWebRequest();//并行任务库 SL5InitiateWebRequest(); } 运行效果一致,如下两图,另外如需源码请点击SL5Ansyc.zip 下载。 本文转自程兴亮博客园博客,原文链接:http://www.cnblogs.com/chengxingliang/archive/2011/11/07/2230319.html,如需转载请自行联系原作者
TFS二次开发系列 TFS二次开发系列:一、TFS体系结构和概念 TFS二次开发系列:二、TFS的安装 TFS二次开发系列:三、TFS二次开发的第一个实例 TFS二次开发系列:四、TFS二次开发WorkItem添加和修改、保存 TFS二次开发系列:五、工作项查询 TFS二次开发系列:六、TFS的版本控制 C#知识总结 C#中Hashtable、Dictionary详解以及写入和读取对比 C#中IDisposable和IEnumerable、IEnumerator C#中Delegate和Event以及它们的区别 C#中Monitor和Lock以及区别 C#知识点总结系列:5、CLR的组成和运转 SQL知识总结 SQL知识整理一:触发器、存储过程、表变量、临时表 SQL知识整理二:锁、游标、索引 SQL知识整理三:变量、全局变量、视图、事务、异常 本文转自程兴亮博客园博客,原文链接:http://www.cnblogs.com/chengxingliang/p/3354408.html,如需转载请自行联系原作者
线性表(Linear List) 线性表是一个线性结构,它是一个含有n≥0个结点的有限序列,对于其中的结点,有且仅有一个开始结点没有前驱但有一个后继结点,有且仅有一个终端结点没有后继但有一个前驱结点,其它的结点都有且仅有一个前驱和一个后继结点。 线性表的顺序存储结构—顺序表 线性表采用顺序存储的方式存储就称之为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。 顺序表的特点 1.容量固定 存储顺序表的元素需要一整块内存空间,因而顺序表的容量一旦确定,便不能更改。 2.访问速度快 假设每个元素占用的空间大小为L个字节,其中第一个单元的存储地址则是该结点的存储地址,并设表中开始结点a1的存储地址(简称为基地址)是LOC(a1),那么结点ai的存储地址LOC(ai)可通过下式计算:LOC(ai)= LOC(a1)+L*(i-1) 1≤i≤n。 数组 线性表的顺序存储结构在C#中的最直接表现形式就是数组。在C#语言中,数组是最基础也是存取速度最快的一种集合类型。数组是引用类型,保存它们所需的内存空间会在托管堆上分配,一旦数组被创建,其中的所有元素将被初始化为它们的默认值。 int[] arrayInt= new int[10]; arrayInt[6] = 5; arrayInt[8] = 3; 以上代码声明了一个值类型int的数组,并把它的长度初始化为10,最后分别给第7和第9个元素赋值。 当数组元素为值类型时,数组对象存放的是值类型对象本身。当元素为引用类型时,数组对象存放的则是对象的引用(指针)。 Control[] arrayControl= new Control[8]; arrayControl[4] = new DropDownList(); arrayControl[6] = new TextBox(); 以上代码声明了一个引用类型Control的数组,并把它的长度初始化为8,最后分别给第5和第7个元素赋值。两个值是分别DropDownList和TextBox对象,虽然它们都继承自Control类,但两者却是不同类,它们的大小不一样。 ArrayList C#中的ArrayList 的容量是根据需要自动扩展的。ArrayList 提供添加、插入或移除某一范围元素的方法。 Insert(int index, object value)方法用于在指定索引处插入一个元素。为了保证顺序表中的每个元素物理上相邻,插入点后面的所有元素都将后移一位。 RemoveAt(int index)方法用于删除指定索引的元素,删除指定元素后,删除点后的所有元素将向前移动一位。 二叉树 二叉树是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树的形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。 二叉树(BinaryTree)是n(n≥0)个结点的有限集,它或者是空集(n=0),或者由一个根结点及两棵互不相交的、分别称作这个根的左子树和右子树的二叉树组成。 这个定义是递归的。由于左、右子树也是二叉树, 因此子树也可为空树。 二叉树的深度优先遍历 1.先序遍历 若二叉树为非空,则过程为: (1) 访问根节点。 (2) 先序遍历左子树。 (3) 先序遍历右子树。 2.中序遍历 若二叉树为非空,则过程为: (1) 按中序遍历左子树。 (2) 访问根结点。 (3) 按中序遍历右子树。 3.后序遍历 若二叉树为非空,则过程为: (1) 按后序遍历左子树。 (2) 按后序遍历右子树 (3) 访问根结点。 本文转自程兴亮博客园博客,原文链接http://www.cnblogs.com/chengxingliang/p/3533908.html:,如需转载请自行联系原作者
继续上一篇”ZigBee On Windows Mobile--1.背景和结构”,今天来讲讲硬件和软件设计。硬件设计主要是做ZigBee模块,输出文件一般包括原理图和PCB图。PCB图是最终给制板厂商的文件,制板厂商将PCB文件转化为Gerb文件进行PCB板加工。软件设计包括两部分,即ZigBee模块中的嵌入式程序和Windows Mobile端的应用程序,这两个软件模块运行在不同的平台之上,硬件上通过UART口进行通信。 硬件设计使用了比较传统的Protel99se,采用了MC13192+GB60的设计和单芯片MC13213的设计原理图下载链接如下: http://files.cnblogs.com/dearsj001/GB60+13192.pdf http://files.cnblogs.com/dearsj001/MC13213.pdf 硬件设计也没有太多可以讲述的,只要按照Freescale给的参考设计,自己根据需求,做相应的小小修改就可以。比较关键的是天线的设计。我们自己没有测试设备(频谱仪一个就10几W),一般而言,就使用给出的参考设计天线,有倒F天线(非平衡式)、双鞭天线(平衡式)等。另外就是板材的选择和板厚也和通信距离有相当大的关系。 嵌入式软件的设计采用CodeWarrior for HCS08 V3.1 开发环境,运用“前后台系统”的模式,前后台系统的基本思想是:硬件中断函数中只做非常少量而且是绝对必须的操作:如设置中断寄存器、保存数据寄存器等,然后置后台标志位,随即退出中断。这些操作称为“前台操作”。而后台操作是一个开放中断的无限循环。在循环中检查各后台标志位,如果某一标志位被置位,则说明有中断发生,立即调用相应的中断服务任务,这些任务被称为“后台操作”。 主程序流程如下图1所示: 图1主程序流程图 TargetInit()执行系统初始化操作,主要包括HCS08的IO、UART和Timer等模块的初始化。ConfigInit()执行配置初始化操作,主要包括SMAC协议和串口通信协议配置。ScheduleLoop()为主调度循环,根据状态来执行不同的任务,如下图2所示。其中的SYS_FEED_DOG()是指喂看门狗操作。 图2 主调度循环流程图 在Windows Mobile设备上运行的用户应用程序,主要执行信息交互和显示功能。进一步说,用户要通过UI将命令发送给ZigBee模块,同时,Windows Mobile设备将ZigBee模块的情况通过UI呈现给用户。在Microsoft Visual Studio 2005的IDE下,安装一个最新的Windows Mobile 6 professional SDK,配合自带的Emulator就可以进行开发和调试。软件可以分为几个模块:串口通信部分、界面UI部分和数据处理部分。由于本人比较熟悉C++,所以我选用了native code进行开发,建立一个基于对话框的MFC工程,将需要的控件加入对话框。具体流程如下图3所示。 图3 Windows Mobile设备应用程序流程图 其中的对话框初始化包括了界面的初始化,要强调的是串口的初始化。我们这里采用的串口参数如下:速率9600bps,1个停止位,无奇偶校验。 工程的运行环境:VS2005 with SP1+.NET CF SP2+windows mobile professional SDK 工程源代码下载:http://files.cnblogs.com/dearsj001/WirelessFutureWM5_Emulator.rar 好了,今天就啰嗦到这里,明天继续讲调试,包括设备调试和模拟器调试。Enjoy! 本文转自施炯博客园博客,原文链接:http://www.cnblogs.com/dearsj001/archive/2008/10/15/1312206.html,如需转载请自行联系原作者
目前,Windows Mobile设备的体积越来越小巧,带串口的设备工业用的比较多,而民用的较少。带CF卡接口的Windows Mobile设备还是有的,但是也在逐渐退出市场的舞台,取而代之的是更加小巧的SD卡,miniSD卡等等。 前面的3篇文章讲述了如何在Windows Mobile设备上实现ZigBee方案,即Windows Mobile设备通过串口和ZigBee模块进行通信。但是,目前带DB9接口(一种串口的物理接口)的Windows Mobile设备太少了。CF卡接口的用途可以有两个,即Storage和IO。通常我们用的CF卡,就是作为Storage来用的;但是,CF卡接口也可以作为IO来用的。那么,我们的目的就很明确了,就是将CF卡接口作为IO,映射出一个串口,那样不就可以和我们的ZigBee模块进行通信了嘛。 CF卡接口转串口可以使用芯片来实现,那样的话,就需要自己画板子,调试,比较麻烦。目前,市场已经有现成的CF卡接口转串口设备可以买到。同样,CF卡接口的GPS设备也有,其实原理都是一样的,GPS也是周期性的将信息通过串口发出来。这两种设备的样品如下图1所示。 图1:CF转串口和CF接口GPS设备示意图 那么,通信的问题解决了,电源问题如何解决呢?因为我们的ZigBee模块也是要供电才能工作的。参考CF接口规范http://zhidao.baidu.com/question/51808984.html,原来CF卡接口也是提供了电源和地的。所以,我们只要使用CF卡接口提供的+5V电源就可以了。CF卡接口的插针如下图所示: 图2:CF卡接口插针 知道了接口规范,我们只要用万用表验证一下就可以了。这样,我们的ZigBee模块就可以通过CF卡接口来和Windows Mobile设备通信了,还解决了供电的问题,一举两得啊! 从应用程序员的角度来说,一般CF卡转串口的设备,我们不需要自己来编写驱动程序,它会自动映射成一个串口,提供我们用户使用。比如,当我们插入CF转串口卡到PDA的时候,我们可以发现一个新的串口1,当我们拔出CF转串口卡的时候,这个串口1又消失了。所以,我们编写应用程序的时候,也是非常灵活的,就像操作本地的串口一样方便。另外一个重要的特性就是,当用户close这个串口的时候,CF卡接口供电就会消失,这样就节省了Windows Mobile设备的电量。 好了,利用CF卡接口外扩这部分就写到这里,希望对大家有所帮助。Enjoy! 本文转自施炯博客园博客,原文链接:http://www.cnblogs.com/dearsj001/archive/2008/10/17/1313822.html,如需转载请自行联系原作者
Asp.Net应用程序中长时间装载页面时显示进度条 在 Asp.Net Web 应用程序中长时间装载页面时显示进度条,虽然是假进度条,不能实时反映装载进度,但是可以告诉用户页面正在装载,以免用户误以为系统故障或死机。新 建一个 Web 项目,添加4个文件:Default.htm;Progressbar.aspx;Second.aspx;common.css。 Default.htm 页面有一个超链,点击之后先装载 Progressbar.aspx,装载完之后装载 Second.aspx,因为 Second.aspx 模拟大页面所以 Page_Load 中主线程挂起 10 秒钟,其间仍显示进度条页面 Progressbar.aspx。代码如下:Default.htm Code Progressbar.aspx (HTML) [copy to clipboard] CODE: <%@ Page language="c#" Codebehind="Progressbar.aspx.cs" AutoEventWireup="false" Inherits="WebApp.Progressbar" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML> <HEAD> <title>进度条</title> <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1"> <meta name="CODE_LANGUAGE" Content="C#"> <meta name="vs_defaultClientScript" content="JavaScript"> <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5";> <link rel="stylesheet" type="text/css" href="common.css" /> <% string strUrl=Request.Params["U"];%> <META http-equiv=Refresh content="0;URL= <%=strUrl%> "> <script language="javascript"> var i = 0; function setPgb(pgbID, pgbValue) { if ( pgbValue <= 100 ) { if (lblObj = document.getElementById(pgbID+'_label')) { lblObj.innerHTML = pgbValue + '%'; // change the label value } if ( pgbObj = document.getElementById(pgbID) ) { var divChild = pgbObj.children[0]; pgbObj.children[0].style.width = pgbValue + "%"; } window.status = "数据读取" + pgbValue + "%,请稍候..."; } if ( pgbValue == 100 ) window.status = "数据读取已经完成"; } function showBar() { setPgb('pgbMain',i); i++; } </script> </HEAD> <BODY onload="setInterval('showBar()',100)"> <TABLE id="Table1" style="WIDTH: 760px" cellSpacing="0" cellPadding="0" align="center" border="0"> <TR height="400"> <TD vAlign="middle" align="center"> <DIV class="bi-loading-status" id="proBar" style="LEFT: 425px; WIDTH: 300px; TOP: 278px; HEIGHT: 44px"> <DIV class="text" id="pgbMain_label" align="left"></DIV> <DIV class="progress-bar" id="pgbMain" align="left"> <DIV style="WIDTH: 10%"></DIV> </DIV> </DIV> </TD> </TR> </TABLE> </BODY> </HTML> Second.aspx(code-behind) [copy to clipboard] CODE: using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing; using System.Web; using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; namespace WebApp { /// <summary> /// Second 的摘要说明。 /// </summary> public class Second : System.Web.UI.Page { private void Page_Load(object sender, System.EventArgs e) { // 在此处放置用户代码以初始化页面 System.Threading.Thread.Sleep(10000); } #region Web 窗体设计器生成的代码 override protected void OnInit(EventArgs e) { // // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。 // InitializeComponent(); base.OnInit(e); } /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器修改 /// 此方法的内容。 /// </summary> private void InitializeComponent() { this.Load += new System.EventHandler(this.Page_Load); } #endregion } } common.css [copy to clipboard] CODE: .bi-loading-status { /*position: absolute;*/ width: 150px; padding: 1px; overflow: hidden; } .bi-loading-status .text { white-space: nowrap; overflow: hidden; width: 100%; text-overflow: ellipsis; padding: 1px; } .bi-loading-status .progress-bar { border: 1px solid ThreeDShadow; background: window; height: 10px; width: 100%; padding: 1px; overflow: hidden; } .bi-loading-status .progress-bar div { background: Highlight; overflow: hidden; height: 100%; filter: Alpha(Opacity=0, FinishOpacity=100, Style=1, StartX=0, StartY=0, FinishX=100, FinishY=0); } 本文转自灵动生活博客园博客,原文链接:http://www.cnblogs.com/ywqu/archive/2008/09/26/1299876.html,如需转载请自行联系原作者
ertainly some of the most talked about layer styles for Photoshop I have seen are the Ultimate Web 2.0 Layer Styles from Deziner Folio. Some of these layer styles have been adapted for Gimp. Deziner Folio also offers a set of 130 gradients that could come in handy for doing Web 2.0-style designs. 本文转自灵动生活博客园博客,原文链接:http://www.cnblogs.com/ywqu/archive/2008/10/04/1303862.html,如需转载请自行联系原作者
做地产类网站或软件,这些应该足够了 按揭贷款mortgage loan 按揭购房to buy a house on mortgage; to mortgage a house 房屋空置率housing vacancy rate 安居工程Comfortable Housing Project 板楼,板式楼slab-type apartment building 搬迁户a relocated unit or household 财产税 property tax; estate(or capital) duty 拆迁补偿费compensation for demolition 拆迁费用removal expense 城镇住房公积金urban housing provident fund 低价住房low-cost housing 二手房second-hand house 房产估价师real estate assessor 房产证property ownership certificate 房屋置换buy or exchange houses 炒房者real estate speculator 房改housing system reform 房管real estate management 房权证property right certificate 房产市场real estate market 房屋空置率housing vacancy rate 福利分房welfare-oriented public housing allocation system 个人购房贷款individual housing loan 公房商品化commercialization of public housing 集资房 houses built with funds collected by the buyers 居民住房建设residential construction 人均住房per-capital housing 现房complete department (or flat) 期房forward delivery housing 商品房commercial residential building 商品房空置the vacancy in commercial housing 政策性住房policy-related house, policy-based house 住房补贴rental allowance; housing allowance 住房分配货币化进程capitalization process of housing distribution/allocation property 资产 property right 产权 subsidiary 附属机构,子公司 valuation 评估 open market value 公开市场价值 leaseback 售后回租(即租回已出售的财产) on a residual basis 剩余法 capital value 资本价值 cost of development 开发费 professional fee 专业费用 finance costs 融资成本 sale proceeds 销售收益 floor area 建筑面积 plaza 购物中心 land use certificate 土地使用证 commercial/residential complex 商住综合楼 land use fee 土地使用费(获得土地使用权后,每年支付国家的使用土地费用) Grant Contract of Land Use Right 土地使用权出让合同 land use term 土地使用期 project approval 项目许可 planning approval 规划许可 commission 佣金 permit 许可证 business license 营业执照 strata-title 分层所有权 public utilities 公共设施 urban planning 城市规划 state-owned land 国有土地 fiscal allotment 财政拨款 grant or transfer 出让或转让 the Municipal Land Administration Bureau 市土地管理局 infrastructure 基础设施 financial budget 财政预算 public bidding 公开招标 auction 拍卖 negotiation /agreement 协议 land efficiency 土地效益 location classification 地段等级 projecting parameter 规划参数 government assignment 政府划拨 administrative institution 行政事业单位 key zones for development 重点开发区 tract 大片土地 biding document 标书 competent authorities 主管部门 construction project 建设项目 planning permit of construction engineering 建设工程规划许可证 go through the formalities 办手续 comprehensive sub-areas 综合分区 reconstruction of old area 旧区改造 purchasing power 购买力 property trust 物业信托 equity 资产净值 cash flows 现金流量 appreciation 增值 disposition 处置 hedge 保值措施 income tax shelter 收入税的庇护 downturn (经济)衰退 wealth maximisation 最大限度的增加财产(同其他投资相比) forecast 预测 rules-of-thumb techniques 经验法 mortgage lender 抵押放贷者 vacancy 空房 discounted cash flow models 折现值现金流量模型 expectation 期望值 letting 出租 equity reversion 权益回收 bad debts 坏帐 depreciation allowances 折旧提成 supplies 日常用品 utilities 公共事业设备 allowances for repairs and maintenance 维修费 unpaid mortgage balance 抵押贷款欠额 stamp duty 印花税 recession 衰退 overproduction 生产过剩 glut 供过于求 high-technology 高科技 investment strategy 投资策略 circulation 发行量 entrepreneur 倡导者,企业家 coliseum 大体育场,大剧院 chambers(商业资本家联合组织的)会所 arena 室内运动场 socioeconomic status 社会经济地位 amenities 便利设施 condominium 个人占有公寓房,一套公寓房的个人所有权 income bracket 收入档次 tenement 分租合住的经济公寓 area code (电话)地区代码 community 社区 assessment 估价 housing residences 住宅 本文转自灵动生活博客园博客,原文链接:http://www.cnblogs.com/ywqu/archive/2008/11/03/1325639.html,如需转载请自行联系原作者
Yuuguu Combines Multi-Service IM Client and Screensharing We've already highlighted Yuuguu, a free screensharing tool for Windows, Mac, and Linux, as one of our favorite tools numerous times in the past. One feature that was missing from Yuuguu, however, was the ability to quickly send invitations via IM and create a group conference on IM with users on different IM services. Now, however, Yuuguu has integrated MSN, Yahoo, AOL and ICQ chat, in addition to its recentintegration with Google Talk. This turns Yuuguu into an IM aggregator with sophisticated screensharing features. This new version of Yuuguu, which was released today, still features all the regular screensharing functions, including the ability to share your screen with up to 30 users at the same time and giving your users control over your screen. Yuuguu also features the ability to set up phone conferences on the fly. We especially like Yuuguu because only the person actually sharing the screen has to install any software, while everybody else can just use a flash-based web interface to see your screen. Too many other free screensharing tools make both sides install software on their machines. The IM functionality works just as advertised and is similar to most other multi-service IM clients. It is, however, not as fully featured as some other clients like Digsby, Trillian, or Adium. You can not send files to other users, for example. Some Limitations We noticed a few minor limitations to Yuuguu, though none of them are real deal breakers. If you have a dual-screen setup, for example, only your first screen can be shared on Yuuguu. Also, you can only add one IM account per service to Yuuguu. If you use more than one Google Talk account, you will have to choose which one to add to Yuuguu. Overall however, the IM integration works very well and adds a new degree of functionality to a tool we already liked a lot. If you are looking for an easy to use screensharing tool, you could do a lot worse than giving Yuuguu a try. 本文转自灵动生活博客园博客,原文链接:http://www.cnblogs.com/ywqu/archive/2008/11/04/1325981.html,如需转载请自行联系原作者
: 在需要调用日期选择的页面放置两个TEXTBOX与BUTTON以选择开始时间与结束时间,并在html代码的 </body>之前加入如下javascript语句: <script language="javascript"> function openModeBegin() { var returnValue=window.showModalDialog("CalendarForm2.aspx",Form1.TextBoxBeginDate.value); Form1.TextBoxBeginDate.value=returnValue; } </script> <script language="javascript"> function openModeEnd() { var returnValue=window.showModalDialog("CalendarForm2.aspx",Form1.TextBoxEndDate.value); Form1.TextBoxEndDate.value=returnValue; } </script> 以上语句定义了两个模态对话框,当调用模态对话框时打开CalendarForm2.aspx页面选择日期,本页面窗体FORM名称为Form1,两个TextBox分别接收传递进来的两个时间值而且应该能互不影响。注意html中窗体的定义应该与javascript中定义的对应并且应该是服务器端运行的,如<form id="Form1" method="post" runat="server">。 在本页面WebForm1.aspx.cs代码部分页面加载Page_Load事件内加入如下语句将定义的javascript行为赋予Button: ButtonBeginDate.Attributes.Add("onclick", "openModeBegin()"); ButtonEndDate.Attributes.Add("onclick", "openModeEnd()"); CalendarForm2.aspx是个临时容器,提供框架调用CalendarForm3.aspx的内容,以备关掉日期选择窗体后无法完成传值,在其html的Head标记之间应该加入如下语句: <script id="clientEventHandlersJS" language="javascript"> <!-- function IFRAME1_onblur() {} //--> </script> CalendarForm2.aspx.cs文件中亦不需要写任何代码,只需在body标记之间加入如下代码: <body runat="server" ID="Body1"> <form id="Form1" method="post" runat="server"> <iframe frameborder="no" src='CalendarForm3.aspx' style="WIDTH: 480px; HEIGHT: 450px" id="IFRAME1" language="javascript" onblur="return IFRAME1_onblur()"></iframe> </form> </body> CalendarForm3.aspx我们实际用到的日期选择页面包含一个日历控件与一个Button一个TextBox,此处直接将日历控件Calendar的选定值传给第一个页面WebForm1.aspx更简单,但我们没有这样做,不直接传值主要是考虑到大多数用户的使用习惯,在此将日历控件选中的值传给页面上的TextBox,按下Button后再传给WebForm1.aspx,还可以在用户误选后容易纠正。 CalendarForm3.aspx的html代码如下,此处只是经过调整让视觉上好看而已的示例,可不用下列代码: <HTML> <HEAD> <title>日期选择窗体</title> <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR"> <meta content="JavaScript" name="vs_defaultClientScript"> <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema"> </HEAD> <body id="Mybody" runat="server" ms_positioning="GridLayout"> <form id="Form1" method="post" runat="server"> <asp:calendar id="Calendar1" style="Z-INDEX: 101; LEFT: 32px; POSITION: absolute; TOP: 16px" runat="server" Height="390px" Width="440px" BorderWidth="1px" BackColor="#FFFFCC" DayNameFormat="Full" ForeColor="#663399" Font-Size="8pt" Font-Names="Verdana" BorderColor="#FFCC66" ShowGridLines="True" PrevMonthText="上个月&amp;lt;&amp;lt;" NextMonthText="下个月&amp;gt;&amp;gt;"> <TodayDayStyle ForeColor="#00C000" BackColor="Khaki"></TodayDayStyle> <SelectorStyle BackColor="#FFCC66"></SelectorStyle> <NextPrevStyle Font-Size="9pt" ForeColor="#FFFFCC"></NextPrevStyle> <DayHeaderStyle Height="1px" BackColor="#FFCC66"></DayHeaderStyle> <SelectedDayStyle Font-Bold="True" BackColor="MediumPurple"></SelectedDayStyle> <TitleStyle Font-Size="9pt" Font-Bold="True" ForeColor="#FFFFCC" BackColor="#990000"></TitleStyle> <OtherMonthDayStyle ForeColor="#CC9966"></OtherMonthDayStyle> </asp:calendar> <asp:TextBox id="TextBox1" style="Z-INDEX: 102; LEFT: 32px; POSITION: absolute; TOP: 416px" runat="server" Visible="False"></asp:TextBox> <asp:Button id="Button1" style="Z-INDEX: 103; LEFT: 216px; POSITION: absolute; TOP: 412px" runat="server" Text="确 定" BorderColor="SteelBlue" ForeColor="White" BackColor="SteelBlue" Width="81px" Height="30px"></asp:Button></form> </body> </HTML> CalendarForm3.aspx.cs代码中只需加入下列两句完成传值动作: private void Calendar1_SelectionChanged(object sender, System.EventArgs e) { TextBox1.Text = Calendar1.SelectedDate.ToLongDateString(); } private void Button1_Click(object sender, System.EventArgs e) { Response.Write("<script language=javascript>window.returnValue='" + TextBox1.Text + "';window.close();</script>"); } 自此一个完整的日期选择即可完成,CalendarForm2.CalendarForm3两个页面可以被重复访问,其他页面要调用只需在html中加入本文开头第一段javascript代码即可。 本文转自灵动生活博客园博客,原文链接: http://www.cnblogs.com/ywqu/archive/2008/11/26/1341401.html,如需转载请自行联系原作者
基本思路 利用反射机制将DataTable的字段与自定义类型的公开属性互相赋值。注意:从DataSet到IList<T>的转换,自定义类型的公开属性必须与DataTable中的字段名称一致,才能到达想要的结果。建议DataTable的定义从数据库来,自定义类型用O/R Mapping的方式获得。 代码说明 /// <summary> /// 泛型集合与DataSet互相转换 /// </summary> public class IListDataSet { /// <summary> /// 集合装换DataSet /// </summary> /// <param name="list">集合</param> /// <returns></returns> /// 2008-08-01 22:08 HPDV2806 public static DataSet ToDataSet( IList p_List ) { DataSet result = new DataSet(); DataTable _DataTable = new DataTable(); if ( p_List.Count > 0 ) { PropertyInfo[] propertys = p_List[0].GetType().GetProperties(); foreach ( PropertyInfo pi in propertys ) { _DataTable.Columns.Add( pi.Name, pi.PropertyType ); } for ( int i = 0; i < p_List.Count; i++ ) { ArrayList tempList = new ArrayList(); foreach ( PropertyInfo pi in propertys ) { object obj = pi.GetValue( p_List[i], null ); tempList.Add( obj ); } object[] array = tempList.ToArray(); _DataTable.LoadDataRow( array, true ); } } result.Tables.Add( _DataTable ); return result; } /// <summary> /// 泛型集合转换DataSet /// </summary> /// <typeparam name="T"></typeparam> /// <param name="list">泛型集合</param> /// <returns></returns> /// 2008-08-01 22:43 HPDV2806 public static DataSet ToDataSet<T>( IList<T> list ) { return ToDataSet<T>( list, null ); } /// <summary> /// 泛型集合转换DataSet /// </summary> /// <typeparam name="T"></typeparam> /// <param name="p_List">泛型集合</param> /// <param name="p_PropertyName">待转换属性名数组</param> /// <returns></returns> /// 2008-08-01 22:44 HPDV2806 public static DataSet ToDataSet<T>( IList<T> p_List, params string[] p_PropertyName ) { List<string> propertyNameList = new List<string>(); if ( p_PropertyName != null ) propertyNameList.AddRange( p_PropertyName ); DataSet result = new DataSet(); DataTable _DataTable = new DataTable(); if ( p_List.Count > 0 ) { PropertyInfo[] propertys = p_List[0].GetType().GetProperties(); foreach ( PropertyInfo pi in propertys ) { if ( propertyNameList.Count == 0 ) { // 没有指定属性的情况下全部属性都要转换 _DataTable.Columns.Add( pi.Name, pi.PropertyType ); } else { if ( propertyNameList.Contains( pi.Name ) ) _DataTable.Columns.Add( pi.Name, pi.PropertyType ); } } for ( int i = 0; i < p_List.Count; i++ ) { ArrayList tempList = new ArrayList(); foreach ( PropertyInfo pi in propertys ) { if ( propertyNameList.Count == 0 ) { object obj = pi.GetValue( p_List[i], null ); tempList.Add( obj ); } else { if ( propertyNameList.Contains( pi.Name ) ) { object obj = pi.GetValue( p_List[i], null ); tempList.Add( obj ); } } } object[] array = tempList.ToArray(); _DataTable.LoadDataRow( array, true ); } } result.Tables.Add( _DataTable ); return result; } /// <summary> /// DataSet装换为泛型集合 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="p_DataSet">DataSet</param> /// <param name="p_TableIndex">待转换数据表索引</param> /// <returns></returns> /// 2008-08-01 22:46 HPDV2806 public static IList<T> DataSetToIList<T>( DataSet p_DataSet, int p_TableIndex ) { if ( p_DataSet == null || p_DataSet.Tables.Count < 0 ) return null; if ( p_TableIndex > p_DataSet.Tables.Count - 1 ) return null; if ( p_TableIndex < 0 ) p_TableIndex = 0; DataTable p_Data = p_DataSet.Tables[p_TableIndex]; // 返回值初始化 IList<T> result = new List<T>(); for ( int j = 0; j < p_Data.Rows.Count; j++ ) { T _t = (T)Activator.CreateInstance( typeof( T ) ); PropertyInfo[] propertys = _t.GetType().GetProperties(); foreach ( PropertyInfo pi in propertys ) { for ( int i = 0; i < p_Data.Columns.Count; i++ ) { // 属性与字段名称一致的进行赋值 if ( pi.Name.Equals( p_Data.Columns[i].ColumnName ) ) { // 数据库NULL值单独处理 if ( p_Data.Rows[j][i] != DBNull.Value ) pi.SetValue( _t, p_Data.Rows[j][i], null ); else pi.SetValue( _t, null, null ); break; } } } result.Add( _t ); } return result; } /// <summary> /// DataSet装换为泛型集合 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="p_DataSet">DataSet</param> /// <param name="p_TableName">待转换数据表名称</param> /// <returns></returns> /// 2008-08-01 22:47 HPDV2806 public static IList<T> DataSetToIList<T>( DataSet p_DataSet, string p_TableName ) { int _TableIndex = 0; if ( p_DataSet == null || p_DataSet.Tables.Count < 0 ) return null; if ( string.IsNullOrEmpty( p_TableName ) ) return null; for ( int i = 0; i < p_DataSet.Tables.Count; i++ ) { // 获取Table名称在Tables集合中的索引值 if ( p_DataSet.Tables[i].TableName.Equals( p_TableName ) ) { _TableIndex = i; break; } } return DataSetToIList<T>( p_DataSet, _TableIndex ); } } 使用范围 1. 可以用在业务层中数据获取,获取DataSet的同时也可以转为IList集合为调用者所使用。 2. 在WebServices中传输自定义类型使用,即传递参数都用DataSet类型(WebServices直接支持的数据类型),在使用前将其转换为IList来使用。 本文转自灵动生活博客园博客,原文链接:http://www.cnblogs.com/ywqu/archive/2009/01/04/1368026.html,如需转载请自行联系原作者
Code The order for reconciling changes to related data is as follows: Delete child records (in this case, delete records from the Orders table) Delete parent records (in this case, delete records from the Customers table) Insert parent records (in this case, insert records in the Customers table) Insert child records (in this case, insert records in the Orders table) 本文转自灵动生活博客园博客,原文链接:http://www.cnblogs.com/ywqu/archive/2009/02/27/1399278.html,如需转载请自行联系原作者
创建数据模型Model 数据模型主要包括数据信息、验证规则以及业务逻辑。 创建Model的方式有多种,可以使用微软的ADO.NET Entity Data Model,也可以使用第三方工具生成实体对象,对于比较简单的实体,我们可以手工添加,此处就是手动敲上去的。 分析:此处定义了新闻实体对象的的一些属性,在每个Property上都存在一些注解,比如字段Title上RequiredAttribute,表明Title栏位是必填字段,如果不填写会显示错误信息”请输入标题!” DataTypeAttribute属性表明此字段的数据类型为文本类型,它是个枚举类型集合,如下: Member name Description Custom Represents a custom data type. DateTime Represents an instant in time, expressed as a date and time of day. Date Represents a date value. Time Represents a time value. Duration Represents a continuous time during which an object exists. PhoneNumber Represents a phone number value. Currency Represents a currency value. Text Represents text that is displayed. Html Represents an HTML file. MultilineText Represents multi-line text. EmailAddress Represents an e-mail address. Password Represent a password value. Url Represents a URL value. ImageUrl Represents a URL to an image. 这些类型,可以分别试试,看看最终效果什么样子的。 DisplayNameAttribute属性表明了此字段要文字说明。 创建View视图 MVC提供了生成View的向导工具,很方便的,如下图流程步骤: 我们在View文件夹下,新建一个新文件夹,命名为News 右击News文件夹,选择Add->Add View功能菜单,出现如下界面: 在View name栏位,我可以给此视图修改名称,比如AddNews, 选中Create a strongly-typed view 栏位,选择刚才定义的实体类Model,并选择View content栏位为Create操作。 其他栏位默认值就OK 最终效果如下图所示: 单击【Add】按钮,即可添加AddNews.aspx视图成功。此文件的核心代码如下所示: <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2> 添¬¨ª加¨®新?闻?</h2> <% using (Html.BeginForm()) {%> <%: Html.ValidationSummary(true) %> <fieldset> <legend>新?闻?</legend> <div class="editor-label"> <%: Html.LabelFor(model => model.Title) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(model => model.Title) %> <%: Html.ValidationMessageFor(model => model.Title) %> </div> <div class="editor-label"> <%: Html.LabelFor(model => model.CreateTime) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(model => model.CreateTime, new { @class = "date"})%> <%: Html.ValidationMessageFor(model => model.CreateTime) %> </div> <div class="editor-label"> <%: Html.LabelFor(model => model.Content) %> </div> <div class="editor-field"> <%: Html.EditorFor(model => model.Content) %> <%: Html.ValidationMessageFor(model => model.Content) %> </div> <p> <input type="submit" value="添¬¨ª加¨®" /> </p> </fieldset> <% } %> <div> <%: Html.ActionLink("Back to List", "Index","Home") %> </div> </asp:Content> 分析: 在日期文本框中,新增加属性new { @class = "date" }),此Class属性是为了稍后的日历控件的显示。要使日期文本框显示日期控件,可以使用Jquery UI,方法是: 1/、Jquery UI官方网站http://www.jqueryUI.com下载最新的 UI类库 2、添加日历控件的CSS文件和JS文件到项目中,如下图 3、在母版页面Site.Master中添加JS的引用,以及页面初始化时绑定日历控件到文本框,代码如下: <link href="http://www.cnblogs.com/Content/jquery.ui.all.css" rel="stylesheet"type="text/css" /> <script src="http://www.cnblogs.com/Scripts/jquery-1.4.1.min.js"type="text/javascript"></script> <script src="http://www.cnblogs.com/Scripts/jquery-ui-1.8.2.custom.min.js"type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function () { $("input:text.date").datepicker( { dateFormat: "yy-mm-dd" }); }); </script> 到此,日历栏位的文本框就可以显示日历控件了,稍后看效果图。 创建Controller文件 在Controllers文件夹下,新增News文件夹; 单击右键,选择Add->Controller,显示如下界面 重命名Controller Name栏位为NewsController,同时选择下方的复选框,最终效果如下图: 单击【Add】按钮,自动产生Controller中的一些方法,这时候对Controller中的方法做一些修改,即可完成添加新闻页面初始化的方法,以及添加新闻功能,代码如下: // GET: /News/Create //完成页面初始化 public ActionResult AddNews() { return View(); } // // POST: /News/Create //完成添加按钮事件 [HttpPost] public ActionResult AddNews(THelperMVC.Models.News.AddNewsModel news) { if (ModelState.IsValid) { newsService.AddNews(); return RedirectToAction("index", "Home"); } else { ModelState.AddModelError("", "请?输º?入¨?合?法¤¡§的Ì?信?息¡é!ê?"); } return View(news); } 至此,MVC的各个层次都已经创建完,让我们看看最终的效果吧。 程序效果图 本文转自灵动生活博客园博客,原文链接:http://www.cnblogs.com/ywqu/archive/2010/06/24/1764062.html ,如需转载请自行联系原作者
Jquery打造AdRotator轮转图片 Asp.net中的AdRotator是一个非常有用的随机显示广告的控件,不足的地方是,每次用户刷心页面,广告随机一次,哪有没有办法页面不刷新,广告每隔一段时间自动翻转呢?答案是肯定的,而且用jquery 很容易实现,接下来我们看一下如何来实现以上说的效果。 1、新建网站 新建一个网站或者在已有的网站中做添加以下文件和文件夹 新增四张图片和Ad.xml文件,供AdRotator控件调用。 2、完善Ad.xml文件 撰写广告XML代码,如下图所示: <?xml version="1.0" encoding="utf-8" ?> <Advertisements> <Ad> <ImageUrl>001.jpg</ImageUrl> <NavigateUrl>ywqu.cnblogs.com</NavigateUrl> <AlternateText>灵动生活</AlternateText> <Impressions>30</Impressions> <Keyword>森森购物</Keyword> </Ad> <Ad> <ImageUrl>002.jpg</ImageUrl> <NavigateUrl>ywqu.cnblogs.com</NavigateUrl> <AlternateText>灵动生活</AlternateText> <Impressions>30</Impressions> <Keyword>森森购物</Keyword> </Ad> <Ad> <ImageUrl>003.jpg</ImageUrl> <NavigateUrl>ywqu.cnblogs.com</NavigateUrl> <AlternateText>灵动生活</AlternateText> <Impressions>30</Impressions> <Keyword>森森购物</Keyword> </Ad> <Ad> <ImageUrl>004.jpg</ImageUrl> <NavigateUrl>ywqu.cnblogs.com</NavigateUrl> <AlternateText>灵动生活</AlternateText> <Impressions>30</Impressions> <Keyword>森森购物</Keyword> </Ad> </Advertisements> 3、添加AdRotator控件 向页面AdRotatorDemo.aspx添加AdRotator控件,代码如下: <div> <asp:AdRotator ID="AdRotator1" runat="server" AdvertisementFile="~/Images/AD/Ad.xml"KeywordFilter="森森购物" /> </div> 分析: AdvertisementFile:引用广告XML文件 KeywordFilter:通过此属性过滤广告,对应XML文件中的keyword属性,这样不同的页面可以使用此属性过滤一些广告内容。 4、Jquery轮转图片 使用jquery使AdRotator控件中的图片轮转起来,代码如下: <script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function () { setInterval(function () { $("#AdRotator1").load(location.href + " #AdRotator1", "" + Math.random() + ""); }, 3000); }); </script> 分析:在以上代码中我们使用了setInterval function,也调用了jQuery load() api,以达到每3秒钟更新一次数据。 引用:Load(function) 在每一个匹配元素的load事件中绑定一个处理函数。如果绑定给window对象,则会在所有内容加载后触发,包括窗口,框架,对象和图像。如果绑定在元素上,则当元素的内容加载完毕后触发。注意:只有当在这个元素完全加载完之前绑定load的处理函数,才会在他加载完后触发。如果之后再绑定就永远不会触发了。所以不要在$(document).ready()里绑定load事件,因为jQuery会在所有DOM加载完成后再绑定load事件。 为了验证是否刷心页面,在页面上加了一个时间标志。 最终运行效果如下: 有以上图可以知,整个页面并没有刷心。可以自由地每隔3秒钟轮转一次。 本文转自灵动生活博客园博客,原文链接:http://www.cnblogs.com/ywqu/archive/2010/10/30/1864875.html ,如需转载请自行联系原作者
zend studio 使用SVN配置工具 在团队开发中,离开不开版本控制工具,比如TFS,SVN,CSV等,小型团队可以选用SVN,最近在开发PHP项目,由于几个人一块开发,于是再次用上了SVN,用zend studio 连接SVN。 步骤如下: 1.在线安装SVN客户端 地址:Eclipse update site URL: http://subclipse.tigris.org/update_1.6.x 2.项目签入到SVN服务器 注:图片顺序为操作顺序 本文转自灵动生活博客园博客,原文链接:http://www.cnblogs.com/ywqu/archive/2011/07/22/2114427.html,如需转载请自行联系原作者
TFS2010合并与分支(Branch and Merge) tfs2010使用了有半年了,仅仅局限于源代码的控管,scrum开发框架和文档管理,至于版本流的管理还没有真正涉及。记得之前使用IBM 的CC CQ,开发版本 UAT版本 上线版本之间切换自如。TFS应该也提供类似的功能:分支和合并。看具体操作 1. 右击项目 2.分支对话框 3.开始生成分支项目 4.分支项目迁入到TFS 5.TFS项目层次结构 这样就产生一个分支项目,可以针对不同的版本流进行修改。 本文转自灵动生活博客园博客,原文链接:http://www.cnblogs.com/ywqu/archive/2011/08/01/2123598.html,如需转载请自行联系原作者
asp.net Jquery图片延迟加载 在电子商务网站中,由于网站图片请求数过多,导致首页加载速度较慢,通过图片延迟加载机制,让用户访问页面的时候,只加载当前屏幕所见内容的图片,从而减少用户请求数量,提升用户体验。 使用步骤: 1.引入Jquery类库和延迟加载类库:http://files.cnblogs.com/ywqu/Jquery%E5%BB%B6%E8%BF%9F%E5%8A%A0%E8%BD%BD.rar 2.首先给图片img加属性original,并对其赋值为图片路径 3.在页面加以下代码 <script language="javascript" type="text/javascript"> $(function () { $("img[original]").lazyload({ placeholder: "../Images/Default/grey.gif", effect: "fadeIn" }); }); </script> 4.最终效果 本文转自灵动生活博客园博客,原文链接:http://www.cnblogs.com/ywqu/archive/2011/08/12/2135840.html,如需转载请自行联系原作者
UML建模系列文章总结 一、为什么要学习UML 二、UML的历史 三、UML的特点 四、UML中的视图 五、UML建模工具 六、UML的应用领域 七、UML的构成 1、需求阶段如何书写Use Case 2、设计阶段如何画用例图(Use-Case Diagram) 3、类与类之间的关系图(Class Diagram,UML图) 4、UML建模之活动图介绍(Activity Diagram) 5、UML建模之状态图(Statechart Diagram) 6、UML建模之时序图(Sequence Diagram) 7、UML建模之业务处理模型(Business Process Model,BPM) 8、UML建模之数据建模(Data Model Diagram) 八、总结 一、为什么要学习UML UML是Unified Modeling Language(统一建模语言)的简称。UML是对软件密集型系统中的制品进行可视化、详述、构造和文档化的语言。制品{Artifact}是指软件开发过程中产生的各种各样的产物,如模型、源代码、测试用例等。 Ø UML建模可以达到以下目的: Ø 使用模型可以更好地理解问题 Ø 使用模型可以加强人员之间的沟通 Ø 使用模型可以更早地发现错误或疏漏的地方 Ø 使用模型可以获得设计结果 Ø 模型为最后的代码提供依据 二、UML的历史 1997年,OMG组织(Object Management Group对象管理组织)发布了统一建模语言(Unified Modeling Language,UML)。UML的目标之一就是为开发团队提供标准通用的设计语言来开发和构建计算机应用。UML提出了一套IT专业人员期待多年的统一的标准建模符号。通过使用UML,这些人员能够阅读和交流系统架构和设计规划--就像建筑工人多年来所使用的建筑设计图一样。 2003年,UML已经获得了业界的认同。在所见过的专业人员的简历中,75%都声称具备UML的知识。然而,在同绝大多数求职人员面谈之后,可以明显地看出他们并不真正了解UML。通常地,他们将UML用作一个术语,或对UML一知半解。大家对UML缺乏理解的这种状况,促进我撰写这篇关于UML 1.4的快速入门文章。当阅读完本文时,您还不具备足够的知识可以在简历上声称自己掌握了UML,但是您已具有了进一步钻研该语言的良好起点。 三、UML的特点 Ø UML的主要特点包括: Ø 统一的标准 Ø 面向对象。UML是支持面向对象软件开发的建模语言。 Ø 可视化、表现能力强 Ø 独立于过程,UML不依赖于特定的软件开发过程。 Ø 概念明确,建模表示法简洁,图形结构清晰,容易掌握和使用。 四、UML中的视图 UML中的视图包括用例视图(Use Case View)、逻辑视图(Logical View)、实现视图(Implementation View)、进程视图(Process View)、部署视图(Deployment View)等,这5个视图被称作”4+1”视图.如下图所示: 逻辑视图。逻辑视图关注功能,不仅包括用户可见的功能,还包括为实现用户功能而必须提供的"辅助功能模块";它们可能是逻辑层、功能模块等。 开发视图。开发视图关注程序包,不仅包括要编写的源程序,还包括可以直接使用的第三方SDK和现成框架、类库,以及开发的系统将运行于其上的系统软件或中间件。开发视图和逻辑视图之间可能存在一定的映射关系:比如逻辑层一般会映射到多个程序包等。 处理视图。处理视图关注进程、线程、对象等运行时概念,以及相关的并发、同步、通信等问题。处理视图和开发视图的关系:开发视图一般偏重程序包在编译时期的静态依赖关系,而这些程序运行起来之后会表现为对象、线程、进程,处理视图比较关注的正是这些运行时单元的交互问题。 物理视图。物理视图关注"目标程序及其依赖的运行库和系统软件"最终如何安装或部署到物理机器,以及如何部署机器和网络来配合软件系统的可靠性、可伸缩性等要求。物理视图和处理视图的关系:处理视图特别关注目标程序的动态执行情况,而物理视图重视目标程序的静态位置问题;物理视图是综合考虑软件系统和整个IT系统相互影响的架构视图。 五、UML建模工具 市面上UML建模工具很多,比较流行的有Rational Rose ,Microsoft Visio、Enterprise Architect 、Visual UML等。《UML建模-面向对象设计》系列文章使用的UML建模工具是Enterprise Architect 7.0,此工具还是比较好用的。 六、UML的应用领域 UML具有很广泛的应用领域,其中最常用的是为软件系统建模,主要领域有:企业信息系统、银行金融系统、电信、交通、国防、航空、零售领域、科学计算、分布式的基于Web的服务。UML还可以用来描述其他非软件系统,比如一个机构的组成和机构的工作流程等等。 七、UML的构成 《UML建模-面向对象设计》系列文章描述了常见的一些UML图,主要包括了用例图(Use Case Diagram)、类图(Class Diagram)、活动图(Activity Diagram)、时序图(Sequence Diagram)、状态图(Statechart Machine Diagram)、部署图(Deployment Diagram)、业务处理模型(Business Process Model)、数据建模(Data Modeling Diagram)等等。 1、需求阶段如何书写Use Case 用例描述文档的书写是系统分析人员对用户需求的深刻理解的体现。是后期时序图和实际开发的重要依据。也可以对作为项目估算的依据,以及根据UC复杂度和开发周期来衡量开发人员的工作效率。因此UC的书写规范及其重要,就工作用的一些经验,比如书写格式、书写内容及其注意事项与大家分享。 2、设计阶段如何画用例图(Use-Case Diagram) 例试图描概括了用例中角色和系统之间的关系,描述了系统功能需求,角色和系统的交互以及系统的反应。是客户和开发人员全貌理解项目需求功能比较好的一个方式,也是后续功能迭代的依据和方向。 3、类与类之间的关系图(Class Diagram,UML图) 本文针对类之间常用的关系进行了简单的描述,主要有:关联关系、泛化、依赖、聚合和组合。 4、UML建模之活动图介绍(Activity Diagram) 活动图描述的是对象活动的顺序关系所遵循的规则,它着重表现的是系统的行为,而非系统的处理过程。活动图能够表示并发活动的情形,活动图是面向对象的。 5、UML建模之状态图(Statechart Diagram) 状态图重点在于描述对象的状态及其状态之间的转移,状态图的基本元素主要有:状态、转移、动作、自身转移、组合状态、进入节点、退出节点、历史状态、并发区域等,状态中的事件分为调用事件(Call)、变化事件(Change)、时间事件(Time)和信号事件(Singal)。最后以实例对状态对进行了分析。 6、UML建模之时序图(Sequence Diagram) 时序图(Sequence Diagram)是显示对象之间交互的图,这些对象是按时间顺序排列的。顺序图中显示的是参与交互的对象及其对象之间消息交互的顺序。时序图中包括的建模元素主要有:对象(Actor)、生命线(Lifeline)、控制焦点(Focus of control)、消息(Message)等等。最后,以课程创建功能演示一时序图实例。 7、UML建模之业务处理模型(Business Process Model,BPM) 业务处理模型是一组活动的集合,描述了活动从开始到结束在时间或者空间上的顺序,以及输入和输出。业务处理模型最终输出要能够满足业务需要。包括输入、输出、资源、消息和目标等元素。最后以实例进一步说明了业务逻辑模型。 8、UML建模之数据建模(Data Model Diagram) 主要介绍了数据库建模所涉及建模元素,主要包括模式 Schema、主键 Primary、外键 Foreign key、关系 Relationship、约束 constraint、索引 Index、触发器 Trigger、存储过程 Stored Procedure、视图 View等等,并配以实例加以说明。 八、总结 至此,《UML建模-面向对象设计》系列文章已经写完,UML建模也就告一段落,在整理这些文中的过程中,参考了许多国内外有价值的文章,在此对这些文章的作者表示感谢。在写这些文章的过程中也得到园子里朋友的鼓励和支持,是你们的支持和鼓励使的我写文章更加有士气和信心,在此表示感谢。希望《UML建模-面向对象设计》系列文章对园子里的朋友有帮助,并希望园子里的朋友批评指正。后续还会发布一些《Net设计模式》系列的文章,主要是以设计原理,实例,源码的方式说明各个设计模式,请大家关注,再此感谢。 最后以一本UML书中的一个例子结束: 如果以建造房子比喻,那么学习UML的过程,就是学习如何从建筑工人成长为建筑师的过程。一个软件工程师不能简单地只是掌握堆砌砖瓦的技术,还应该有设计高楼大厦的能力。 本文转自灵动生活博客园博客,原文链接http://www.cnblogs.com/ywqu/archive/2009/12/29/1634804.html,如需转载请自行联系原作者
转自 AE 栅格图分级渲染 ArcEngine对矢量数据进行风格化实在是得心应手,同样的对于栅格图像也能进行风格化!以前没接触过,今天正好需要,做出了栅格图像的渲染!下面实现的思路: 1.定义渲染的一系列接口 2.判断图像是否建立了直方图,如果没有则进行创建。 3.定义颜色序列,为渲染提供渲染的方案。 4.调用Render方法进行渲染。 下面是代码:有两个方法,一个是加载栅格数据,一个是进行渲染,接着在事件里面调用方法,实现图像渲染! /// 栅格分类专题图 /// /// 栅格图层 public static void funColorForRaster_Classify(IRasterLayer pRasterLayer) { IRasterClassifyColorRampRenderer pRClassRend = new RasterClassifyColorRampRenderer() as IRasterClassifyColorRampRenderer; IRasterRenderer pRRend = pRClassRend as IRasterRenderer; IRaster pRaster = pRasterLayer.Raster; IRasterBandCollection pRBandCol = pRaster as IRasterBandCollection; IRasterBand pRBand = pRBandCol.Item(0); if (pRBand.Histogram == null) { pRBand.ComputeStatsAndHist(); } pRRend.Raster = pRaster; pRClassRend.ClassCount = 10; pRRend.Update(); IRgbColor pFromColor = new RgbColor() as IRgbColor; pFromColor.Red = 255; pFromColor.Green = 0; pFromColor.Blue = 0; IRgbColor pToColor = new RgbColor() as IRgbColor; pToColor.Red = 0; pToColor.Green = 0; pToColor.Blue = 255; IAlgorithmicColorRamp colorRamp = new AlgorithmicColorRamp() as IAlgorithmicColorRamp; colorRamp.Size = 10; colorRamp.FromColor = pFromColor; colorRamp.ToColor = pToColor; bool createColorRamp; colorRamp.CreateRamp(out createColorRamp); IFillSymbol fillSymbol = new SimpleFillSymbol() as IFillSymbol; for (int i = 0; i < pRClassRend.ClassCount; i++) { fillSymbol.Color = colorRamp.get_Color(i); pRClassRend.set_Symbol(i, fillSymbol as ISymbol); pRClassRend.set_Label(i, pRClassRend.get_Break(i).ToString("0.00")); } pRasterLayer.Renderer = pRRend; } /// /// 打开遥感图像 /// /// 图像的地址 /// IRasterLayer private IRasterLayer OpenImage(string imagePath) { string ws = Path.GetDirectoryName(imagePath); string fbs = Path.GetFileName(imagePath); IWorkspaceFactory pWork = new RasterWorkspaceFactory(); IRasterWorkspace pRasterWs = pWork.OpenFromFile(ws,0) as IRasterWorkspace; IRasterDataset pRasterDataset = pRasterWs.OpenRasterDataset(fbs); IRasterLayer pRasterLayer = new RasterLayer() as IRasterLayer; pRasterLayer.CreateFromDataset(pRasterDataset); return pRasterLayer; } 事件的逻辑: axMapControl1.Map.AddLayer(OpenImage(filePath)); axMapControl1.ActiveView.Refresh(); funColorForRaster_Classify(axMapControl1.get_layer(0) as IRasterLayer);//only one RasterLayer axMapControl1.Activeview.Refresh(); 下面是渲染前后的效果图: 没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。 本文转自wenglabs博客园博客,原文链接:http://www.cnblogs.com/arxive/p/6821287.html,如需转载请自行联系原作者
不多说,直接上干货! 问题详情 在这里面如何英文改中文的吗? 莫非要把linux的语言环境给改了?? 我找找网页的语言字体怎么更改下 找到对应页面,修改成中文 解决办法 刷新下,即可 本文转自xiaotie博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/8196518.html 如需转载请自行联系原作者
不多说,直接上干货! 现有一份数据如下。 下载日志数据并分析 到搜狗实验室下载用户查询日志 1) 介绍 搜索引擎查询日志库设计为包括约1个月(2008年6月)Sogou搜索引擎部分网页查询需求及用户点击情况的网页查询日志数据集合。为进行中文搜索引擎用户行为分析的研究者提供基准研究语料。 2) 格式说明 数据格式为:访问时间\t用户ID\t[查询词]\t该URL在返回结果中的排名\t用户点击的顺序号\t用户点击的URL 其中,用户ID是根据用户使用浏览器访问搜索引擎时的Cookie信息自动赋值,即同一次使用浏览器输入的不同查询对应同一个用户ID。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/8215392.html,如需转载请自行联系原作者
使用Notepad++开发C#,一个复杂点的csscript脚本: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 //css_dir ..\..\lib; //css_ref Geb.Image.dll; //css_ref Geb.Image.ShapeAnalysis.dll; //css_ref Geb.Utils.dll; //css_ref Geb.Utils.WinForm.dll; //css_co /unsafe; using System; using Geb.Image; unsafe class Program { public static void Main() { ImageArgb32 img = new ImageArgb32(300,200); img.Fill(Argb32.RED); img.ShowDialog(); } } // css_dir 设置搜索库目录的路径; // css_ref 引用dll; // css_co 设置编译参数; 本文转自xiaotie博客园博客,原文链接:http://www.cnblogs.com/xiaotie/p/3298401.html,如需转载请自行联系原作者
网上的视频很多都是分片的flv文件,怎么把他们合为一体呢?GUI工具就不考虑了,不适合批量执行,不适合在后台运行。有没有命令行工具或库可以实现呢? ffmpeg 提供了一个方法: (1)先把flv文件转换成mpeg; (2)将多个mpeg文件合并成1个独立的mpeg文件(二进制合并即可) (3)将独立的mpeg文件转换成独立的flv文件。 网上搜到的最多的也是这种解决办法。这种方法有两个缺点: (1)需要两遍转码,非常耗时; (2)转换后的独立的mpeg文件比原视频要短一点点。 木有办法了,只好另寻他路。有人说有一个flvmerge.exe 程序可以将多个flv合并成一个,可惜的是俺搜了很久,都没找到这个程序,最后还是在一款免费软件里把这个“flvmerge.exe”文件给揪出来了,不幸的是,这个“flvmerge.exe”得不到正确的结果。 润之同学说过,自己动手,丰衣足食。上 github 上搜“flvmerge”,发现两个项目,“flvmerge”和“flvmerger”,都是C写的。前者不依赖于第三方库,后者依赖于第三方库,那么就从第一个开始吧。 看了看它的代码,知道了flv文件合并的原理: (1) flv 文件由1个header和若干个tag组成; (2) header记录了视频的元数据; (3) tag 是有时间戳的数据; (4) flv合并的原理就是把多个文件里的tag组装起来,调整各tag的时间戳,再在文件起始处按个头部。 下面是我参照 flvmerge 项目,用linqpad写的一个C#版本的 flvmerge 代码: 1 void Main() 2 { 3 String path1 = "D:\\Videos\\Subtitle\\OutputCache\\1.flv"; 4 String path2 = "D:\\Videos\\Subtitle\\OutputCache\\2.flv"; 5 String path3 = "D:\\Videos\\Subtitle\\OutputCache\\3.flv"; 6 String output = "D:\\Videos\\Subtitle\\OutputCache\\output.flv"; 7 8 using(FileStream fs1 = new FileStream(path1, FileMode.Open)) 9 using(FileStream fs2 = new FileStream(path2, FileMode.Open)) 10 using(FileStream fs3 = new FileStream(path3, FileMode.Open)) 11 using(FileStream fsMerge = new FileStream(output, FileMode.Create)) 12 { 13 Console.WriteLine(IsFLVFile(fs1)); 14 Console.WriteLine(IsFLVFile(fs2)); 15 Console.WriteLine(IsFLVFile(fs3)); 16 17 if(IsSuitableToMerge(GetFLVFileInfo(fs1),GetFLVFileInfo(fs2)) == false 18 || IsSuitableToMerge(GetFLVFileInfo(fs1),GetFLVFileInfo(fs3)) == false) 19 { 20 Console.WriteLine("Video files not suitable to merge"); 21 } 22 23 int time = Merge(fs1,fsMerge,true,0); 24 time = Merge(fs2,fsMerge,false,time); 25 time = Merge(fs3,fsMerge,false,time); 26 Console.WriteLine("Merge finished"); 27 } 28 } 29 30 const int FLV_HEADER_SIZE = 9; 31 const int FLV_TAG_HEADER_SIZE = 11; 32 const int MAX_DATA_SIZE = 16777220; 33 34 class FLVContext 35 { 36 public byte soundFormat; 37 public byte soundRate; 38 public byte soundSize; 39 public byte soundType; 40 public byte videoCodecID; 41 } 42 43 bool IsSuitableToMerge(FLVContext flvCtx1, FLVContext flvCtx2) 44 { 45 return (flvCtx1.soundFormat == flvCtx2.soundFormat) && 46 (flvCtx1.soundRate == flvCtx2.soundRate) && 47 (flvCtx1.soundSize == flvCtx2.soundSize) && 48 (flvCtx1.soundType == flvCtx2.soundType) && 49 (flvCtx1.videoCodecID == flvCtx2.videoCodecID); 50 } 51 52 bool IsFLVFile(FileStream fs) 53 { 54 int len; 55 byte[] buf = new byte[FLV_HEADER_SIZE]; 56 fs.Position = 0; 57 if( FLV_HEADER_SIZE != fs.Read(buf,0,buf.Length)) 58 return false; 59 60 if (buf[0] != 'F' || buf[1] != 'L' || buf[2] != 'V' || buf[3] != 0x01) 61 return false; 62 else 63 return true; 64 } 65 66 FLVContext GetFLVFileInfo(FileStream fs) 67 { 68 bool hasAudioParams, hasVideoParams; 69 int skipSize, readLen; 70 int dataSize; 71 byte tagType; 72 byte[] tmp = new byte[FLV_TAG_HEADER_SIZE+1]; 73 if (fs == null) return null; 74 75 FLVContext flvCtx = new FLVContext(); 76 fs.Position = 0; 77 skipSize = 9; 78 fs.Position += skipSize; 79 hasVideoParams = hasAudioParams = false; 80 skipSize = 4; 81 while (!hasVideoParams || !hasAudioParams) 82 { 83 fs.Position += skipSize; 84 85 if (FLV_TAG_HEADER_SIZE+1 != fs.Read(tmp,0,tmp.Length)) 86 return null; 87 88 tagType = (byte)(tmp[0] & 0x1f); 89 switch (tagType) 90 { 91 case 8 : 92 flvCtx.soundFormat = (byte)((tmp[FLV_TAG_HEADER_SIZE] & 0xf0) >> 4) ; 93 flvCtx.soundRate = (byte)((tmp[FLV_TAG_HEADER_SIZE] & 0x0c) >> 2) ; 94 flvCtx.soundSize = (byte)((tmp[FLV_TAG_HEADER_SIZE] & 0x02) >> 1) ; 95 flvCtx.soundType = (byte)((tmp[FLV_TAG_HEADER_SIZE] & 0x01) >> 0) ; 96 hasAudioParams = true; 97 break; 98 case 9 : 99 flvCtx.videoCodecID = (byte)((tmp[FLV_TAG_HEADER_SIZE] & 0x0f)); 100 hasVideoParams = true; 101 break; 102 default : 103 break; 104 } 105 106 dataSize = FromInt24StringBe(tmp[1],tmp[2],tmp[3]); 107 skipSize = dataSize - 1 + 4; 108 } 109 110 return flvCtx; 111 } 112 113 int FromInt24StringBe(byte b0, byte b1, byte b2) 114 { 115 return (int)((b0<<16) | (b1<<8) | (b2)); 116 } 117 118 int GetTimestamp(byte b0, byte b1, byte b2, byte b3) 119 { 120 return ((b3<<24) | (b0<<16) | (b1<<8) | (b2)); 121 } 122 123 void SetTimestamp(byte[] data, int idx, int newTimestamp) 124 { 125 data[idx + 3] = (byte)(newTimestamp>>24); 126 data[idx + 0] = (byte)(newTimestamp>>16); 127 data[idx + 1] = (byte)(newTimestamp>>8); 128 data[idx + 2] = (byte)(newTimestamp); 129 } 130 131 int Merge(FileStream fsInput, FileStream fsMerge, bool isFirstFile, int lastTimestamp = 0) 132 { 133 int readLen; 134 int curTimestamp = 0; 135 int newTimestamp = 0; 136 int dataSize; 137 byte[] tmp = new byte[20]; 138 byte[] buf = new byte[MAX_DATA_SIZE]; 139 140 fsInput.Position = 0; 141 if (isFirstFile) 142 { 143 if(FLV_HEADER_SIZE+4 == (fsInput.Read(tmp,0,FLV_HEADER_SIZE+4))) 144 { 145 fsMerge.Position = 0; 146 fsMerge.Write(tmp,0,FLV_HEADER_SIZE+4); 147 } 148 } 149 else 150 { 151 fsInput.Position = FLV_HEADER_SIZE + 4; 152 } 153 154 while(fsInput.Read(tmp, 0, FLV_TAG_HEADER_SIZE) > 0) 155 { 156 dataSize = FromInt24StringBe(tmp[1],tmp[2],tmp[3]); 157 curTimestamp = GetTimestamp(tmp[4],tmp[5],tmp[6],tmp[7]); 158 newTimestamp = curTimestamp + lastTimestamp; 159 SetTimestamp(tmp,4, newTimestamp); 160 fsMerge.Write(tmp,0,FLV_TAG_HEADER_SIZE); 161 162 readLen = dataSize+4; 163 if (fsInput.Read(buf,0,readLen) > 0) { 164 fsMerge.Write(buf, 0, readLen); 165 } else { 166 goto failed; 167 } 168 } 169 170 return newTimestamp; 171 172 failed: 173 throw new Exception("Merge Failed"); 174 } 测试通过,合并速度很快! 不过,这个方法有一个缺点:没有将各个文件里的关键帧信息合并,这个关键帧信息,切分flv文件时很重要,合并时就没那么重要了。如果确实需要的话,可以用 yamdi 来处理。 本文转自xiaotie博客园博客,原文链接:http://www.cnblogs.com/xiaotie/p/3441030.html,如需转载请自行联系原作者
作为开发软件的程序员,应在力所能及的情况下使用正版软件。最近一直在用VisualStudio 2012 Express Desktop/Web 版本开发项目。VisualStudio 2012 Express 是免费的,功能基本上够用,但是还是有很多不足,如: (1)无法安装扩展;这个很致命,比如,想安装IronPython,没办法;想安装 Mono for Android,没办法。 (2)无法同时打开Winform项目、 C++ 项目和Web项目; (3)解决方案下不能建虚拟目录。 下面,我们来一步步克服上面问题,打造一款 正版、免费又强大的 Visual Studio 2012 IDE。本文的初始版本在有的电脑上有问题,下面是修改后的版本。 第一步: 下载,安装 Visual Studio Express for Windows Desktop 和 Visual Studio Express for Web。地址: http://www.microsoft.com/visualstudio/eng/products/visual-studio-express-products 下载安装之后,在线注册一下,就可以免费使用了。 第二步: 下载,安装 Visual Studio 2012 Shell,包括 Visual Studio Integrated Shell 和 Visual Studio Isolated Shell ,地址: http://msdn.microsoft.com/zh-cn/library/vstudio/bb685612.aspx 这个也是免费的,你可以用这个Shell开发自己的IDE工具。这个Shell 很方便安装扩展,并且解决方案下能够建虚拟目录。 第三步: 将上面的 Visual Studio Express for Windows Desktop 和 Visual Studio Express for Web 作为插件,集成到 Visual Studio 2012 Shell 之中。 这一步是最关键一步,下面详细说明。 (1)修改 Visual Studio Shell 的配置文件 以我的电脑为例(Win7,32位)。在 Microsoft Visual Studio 11.0\Common7\IDE 目录下,有三个 exe 程序:devenv.exe 程序是 Visual Studio 2012 Shell 的可执行程序。VWDExpress.exe 是 Visual Studio Express for Web 的可执行程序,WDExpress.exe 是 Visual Studio Express for Windows Desktop 的可执行程序。这三个程序分别对应有各自的 ×.pkgdef 文件,规定了这个程序的扩展目录。devenv.exe 对应的是 devenv.pkgdef 文件。 打开 devenv.pkgdef 文件,将内容更改为: [$Initialization$] "ApplicationExtensionsFolder" = "$RootFolder$\Common7\IDE\Extensions" "PkgDefSearchPath" = "$ApplicationExtensionsFolder$; \ $RootFolder$\Common7\IDE\CommonExtensions; \ $RootFolder$\Common7\IDE\WDExpress; \ $RootFolder$\Common7\IDE\WDExpressExtensions; \ $RootFolder$\Common7\IDE\VWDExpress; \ $RootFolder$\Common7\IDE\VWDExpressExtensions; \ $RootFolder$\Common7\IDE\Extensions\Microsoft\VC\ClassWizard; \ $RootFolder$\Common7\IDE\devenv.vc.pkgdef;" "UserExtensionsRootFolder" = "$AppDataLocalFolder$\Extensions" "RegistryRoot" = "Software\Microsoft\VisualStudio\11.0" 上面这个配置文件简单解释一下。 $RootFolder$\Common7\IDE\Extensions 是 VS Shell默认加载插件的位置,一般安装的第三方插件都会安装到这个目录下。$RootFolder$\Common7\IDE\CommonExtensions 是 VS 自带的插件,如 Editor 等等。 $RootFolder$\Common7\IDE\WDExpress 和 $RootFolder$\Common7\IDE\WDExpressExtensions 是 Visual Studio 2012 for Desktop(刨除其中的VC部分) ,我们将它当作插件加载进来。 $RootFolder$\Common7\IDE\VWDExpress 和 $RootFolder$\Common7\IDE\VWDExpressExtensions 是 Visual Studio 2012 for Web ,我们将它当作插件加载进来。 $RootFolder$\Common7\IDE\Extensions\Microsoft\VC\ClassWizard 和 $RootFolder$\Common7\IDE\devenv.vc.pkgdef 的作用是将 VC 当作插件加载进来。 但是, WDExpress 、 VWDExpress 和 VC 自身不是插件,如果不写配置文件的话,他们是加载不进来的。下面,我们来写插件文件,将它们配置成插件。 (2)将 WDExpress 配置成插件 进入 Common7\IDE\WDExpress 目录下,添加一个名为 extension.vsixmanifest 的文本文件,内容如下: <?xml version="1.0" encoding="utf-8"?> <Vsix Version="1.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2010"> <Identifier Id="WD Express..7DB76FEF-2C49-4E20-AD04-17DDE708C56B"> <Name>WD Express</Name> <Author>Microsoft</Author> <Version>1.0</Version> <Description>WD Express Tools</Description> <Locale>1033</Locale> <License>ms-pl.rtf</License> <SupportedProducts> <VisualStudio Version="11.1"> <Edition>Pro</Edition> <Edition>VDExpress</Edition> <Edition>IntegratedShell</Edition> </VisualStudio> </SupportedProducts> <SystemComponent>true</SystemComponent> <InstalledByMsi>true</InstalledByMsi> <SupportedFrameworkRuntimeEdition MinVersion="2.0" MaxVersion="4.5" /> </Identifier> <References /> <Content> <ProjectTemplate>ProjectTemplates</ProjectTemplate> <ItemTemplate>ItemTemplates</ItemTemplate> </Content> </Vsix> (3)将 VWDExpress 配置成插件 进入 Common7\IDE\VWDExpress 目录下,添加一个名为 extension.vsixmanifest 的文本文件,内容如下: <?xml version="1.0" encoding="utf-8"?> <Vsix Version="1.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2010"> <Identifier Id="VWD Express..7DB76FEF-2C49-4E20-AD04-17DDE708C5DD"> <Name>VWD Express</Name> <Author>Microsoft</Author> <Version>1.0</Version> <Description>VWD Express Tools</Description> <Locale>1033</Locale> <License>ms-pl.rtf</License> <SupportedProducts> <VisualStudio Version="11.1"> <Edition>Pro</Edition> <Edition>VWDExpress</Edition> <Edition>IntegratedShell</Edition> </VisualStudio> </SupportedProducts> <SystemComponent>true</SystemComponent> <InstalledByMsi>true</InstalledByMsi> <SupportedFrameworkRuntimeEdition MinVersion="2.0" MaxVersion="4.5" /> </Identifier> <References /> <Content> <ProjectTemplate>ProjectTemplates</ProjectTemplate> <ItemTemplate>ItemTemplates</ItemTemplate> </Content> </Vsix> (4)将 VC 配置成插件 devenv.vc.pkgdef 文件就是VC的插件配置,这个文件是不存在的。我们在 Common7\IDE 目录下,建立一个名为 devenv.vc.pkgdef 的文本文件,内容如下: // Override the VC root for templates [$RootKey$\Projects\{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}] "DesignerTemplatesDir"="$ShellFolder$\VC\DesignerTemplates_WDExpress" "ItemTemplatesDir"="$ShellFolder$\VC\VCProjectItems_WDExpress" "ProjectTemplatesDir"="$ShellFolder$\VC\VCProjects_WDExpress" [$RootKey$\NewProjectTemplates\TemplateDirs\{F1C25864-3097-11D2-A5C5-00C04F7968B4}\/1] "TemplatesDir"="$ShellFolder$\VC\VCProjects_WDExpress" [$RootKey$\Projects\{7C3490A3-8632-43C5-8A60-07DC2F450870}\AddItemTemplates\TemplateDirs\{3A3E1789-3E35-47B0-8567-D2FB407CC63D}\/1] "TemplatesDir"="$ShellFolder$\VC\VCProjectItems_WDExpress\PropertySheets" [$RootKey$\Projects\{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\AddItemTemplates\TemplateDirs\{F1C25864-3097-11D2-A5C5-00C04F7968B4}\/1] "TemplatesDir"="$ShellFolder$\VC\VCProjectItems_WDExpress" [$RootKey$\Projects\{8BC9CEBA-8B4A-11D0-8D11-00A0C91BC942}\AddItemTemplates\TemplateDirs\{F1C25864-3097-11D2-A5C5-00C04F7968B4}\/3] "TemplatesDir"="$ShellFolder$\VC\VCAddClass_WDExpress" [$RootKey$\Projects\{7D6034C3-AFB8-05CB-2A75-DAA65E89BE83}\AddItemTemplates\TemplateDirs\{F1C25864-3097-11D2-A5C5-00C04F7968B4}\/1] "TemplatesDir"="$ShellFolder$\VC\VCProjectItems_WDExpress" [$RootKey$\Projects\{A2FE74E1-B743-11d0-AE1A-00A0C90FFFC3}\AddItemTemplates\TemplateDirs\{F1C25864-3097-11D2-A5C5-00C04F7968B4}\/1] "TemplatesDir"="$ShellFolder$\VC\VCNewItems_WDExpress" (5)让Visual Studio Shell 重新加载插件 接着,删除插件缓存文件。我的在 C:\Users\Administrator\AppData\Local\Microsoft\VisualStudio\11.0\Extensions 目录中,不同的系统可能在不同的位置。删除这个目录下的所有文件。 然后,通过控制台程序,进入到 Microsoft Visual Studio 11.0\Common7\IDE 目录下,执行下面命令: .\devenv.exe /setup ==== 这样就得到了一个集成C#,VB,C++,Web开发的,可正常安装扩展的,支持建立虚拟目录的正版免费 Visual Studio IDE。整个过程就是做了这么一件事情——设置配置文件,将Express for Desktop/Web以及VC配置成Visual Studio的插件,其它地方未作修改。 注:可能是加载项目模板缓存的问题,第一次启动时如果窗体假死,直接关掉它,再重新打开就好了。 ==== 说几句其他的话: (1)有人怀疑这样做的意义,认为VS 各种版本的注册码网上多的事,这样做多此一举。但好歹,这样实在对方授权范围内,而直接下载用注册码的是在对方授权范围外; (2)即使微软纵容 D 版满天飞,但是嗟来之食,总归无味; (3)通过上面操作,可以对Visual Studio 的插件结构有所了解,进而定制对自己最合适的IDE; (4)黑客精神第一条:这世上充满著等着被解决的迷人问题。上面解决问题的过程中进行了很多大胆的假设、猜想和验证,然后一步一步的得到结果,这种过程也是很迷人的。 本文转自xiaotie博客园博客,原文链接:http://www.cnblogs.com/xiaotie/archive/2013/02/22/2922204.html,如需转载请自行联系原作者
前面博客 全网最详细的Git学习系列之介绍各个Git图形客户端(Windows、Linux、Mac系统皆适用ing)(图文详解) 全网最详细的Git学习系列之安装各个Git图形客户端(Windows、Linux、Mac系统皆适用ing)(图文详解) 使用 Git命令有时候确实不怎么方便,特别是每次都要输入密码,如果配置 SSH 的方式,又实在是很麻烦。(当然,必须使用 Windows 神器才有方便友好的客户端图形界面啦!!!) TortoiseGit基本操作克隆项目 打开资源管理器(我的电脑/计算机), 进入规划好的某个目录中, 然后在空白处点击鼠标右键,选择 TortoiseGit --> 克隆... (Clone...)。 弹出克隆项目对话框: 在对话框的 URL中输入项目地址,如: https://github.com/cncounter/LispGentleIntro.git 确定本地目录,然后点击 确定 按钮, 等待完成后,点击关闭按钮即可。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/7987127.html如需转载请自行联系原作者
不多说,直接上干货! IBM SPSS Statistics 为业务经理和分析人员提供解决基本业务和研究问题所需的核心统计过程。该软件提供的工具使用户能够快速查看数据、为其他测试拟定假设情况、执行澄清变量之间关系的过程、创建集群、发现趋势和进行预测。 IBM SPSS Statistics 包含以下主要功能: (1)线性模型提供各种回归和高级统计过程,旨在适应描述复杂关系的数据的固有特征。 (2)非线性模型能够将较为复杂的模型应用于数据。 (3)模拟功能帮助分析人员自动模拟许多可能的结果(输入不确定时),同时改进风险分析和决策制定。 (4)定制表使用户能够轻松理解其数据,并针对不同受众以不同风格快速汇总结果。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/8013225.html,如需转载请自行联系原作者
Silverlight 5 的RC版本已经出来了,本文将讲解RC版本中一个非常实用的小功能,SaveFileDialog保存文件指定默认名称和OpenFileDialog打开文件指定默认路径。本文使用 Silverlight实用窍门系列:50.InkPresenter涂鸦板的基本使用,以及将效果保存为Png图片的源码实例。 一、SaveFileDialog保存文件指定默认名称 在SaveFileDialog类中新增了一个属性DefaultFileName即可指定想要保存的文件的默认名称。下面请看代码如下: SaveFileDialog sfd = new SaveFileDialog(); sfd.Filter = "PNG Files (*.png)|*.png|All Files (*.*)|*.*"; sfd.DefaultExt = ".png"; sfd.FilterIndex = 1; sfd.DefaultFileName = "DefaultImg"; 运行效果如下: 在这里看图可以知道,它会弹出一个下载警告,询问是否要保存文件。我们可以在项目-“属性”之中勾选“在浏览器内运行时需要提升的信任”以取消下载警告。如下图所示: 其最终实现效果如下图所示: 二、OpenFileDialog打开文件指定默认路径 在打开文件的时候,设置需要打开文件的默认目录,这是一个很实用的功能。Silverlight 5 RC版本中在OpenFileDialog类中新增了一个InitialDirectory属性来实现,代码如下: OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "PNG Files (*.png)|*.png|All Files (*.*)|*.*"; ofd.FilterIndex = 1; ofd.InitialDirectory = "D:\\fir";if (ofd.ShowDialog() == true) { Stream stream = ofd.File.OpenRead(); BitmapImage bi = new BitmapImage(); bi.SetSource(stream); showIP.Source = bi; stream.Close(); } 最后其效果如下图所示: 本文使用VS2010 SP1版本+Silverlight 5 RC 编写,如需源码请点击SL5RC_InkPresenter.zip下载源码。 推荐一下自己的蚂蜂窝游记:http://www.mafengwo.cn/u/cirojessie.html 本文转自程兴亮博客园博客,原文链接:http://www.cnblogs.com/chengxingliang/archive/2011/09/13/2171149.html,如需转载请自行联系原作者
在FreeBSD主机上执行PHP页面报以下错误,Fatal error: Call to undefined function session_start() ,应该是在没有安装扩展,于是: 在操作系统上执行以下步骤: 本文转自灵动生活博客园博客,原文链接:http://www.cnblogs.com/ywqu/archive/2011/08/14/2138060.html,如需转载请自行联系原作者
不多说,直接上干货! http://cassandra.apache.org/ Apache Cassandra是一套开源分布式NoSQL数据库系统。它最初由Facebook开发,用于储存收件箱等简单格式数据,集Google BigTable的数据模型与Amazon Dynamo的完全分布式的架构于一身。Facebook于2008将 Cassandra 开源,此后,由于Cassandra良好的可扩放性,被Digg、Twitter等知名Web 2.0网站所采纳,成为了一种流行的分布式结构化数据存储方案。 它是一个开源的、分布式、无中心、支持水平扩展、高可用的KEY-VALUE类型的NOSQL数据库。 官网文档地址是在: http://cassandra.apache.org/doc/latest/ 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/8031459.html如需转载请自行联系原作者
最近我开始在windows环境中使用Cassandra,虽然在Cassandra站点的安装命令非常清楚和精简,我仍然在环境配置上遇到一些问题。所以我想为后来者分享下我的经验。 官网下载地址 http://cassandra.apache.org/ http://cassandra.apache.org/download/ http://www.apache.org/dyn/closer.lua/cassandra/3.11.1/apache-cassandra-3.11.1-bin.tar.gz windows环境里下载且安装配置Cassandra(最新的3.11.1版本) 第一步:安装JDK8.0以上的JDK版本,配置好相关的环境变量。8.0以下的JDK将无法正常启动Cassandra服务,造成不必要的麻烦。 第二步:安装python2.7版本或以上的版本用于启动cqlsh的shell命令 第三步 : 在Cassandra官网上下载最新的Cassandra版本,本文使用的是apache-cassandra-3.11.1,解压到你想要的目录。在环境变量中设置CASSANDRA_HOME为你的Cassandra安装目录。 第四步:修改cassandra.yaml文件中的配置参数。 我这里是放在D:\SoftWare下 接下来,对windows里的环境变量设置 接下来是,修改cassandra里的conf目录下配置文件 (1)使用Notepad++打开cassandra.yaml文件,修改如下参数: data_file_directories: - D:\SoftWare\apache-cassandra-3.11.1\data 注意:-后面需要有空格 修改为 commitlog_directory: D:\SoftWare\apache-cassandra-3.11.1\commitlog 修改为 saved_caches_directory: D:\SoftWare\apache-cassandra-3.11.1\saved_caches (2)使用Notepad++打开log4j-server.properties文件,修改如下参数: 为:log4j.appender.R.File=D:\SoftWare\apache-cassandra-3.11.1\logs 双击bin目录下的cassandra.bat启动cassandra服务 出现下面的图后表示服务启动成功了,记住,这个cmd的窗口不要关闭,关闭了好像服务就被一起关闭了,接下来客端的连接好像就不行了。 启动之后, 现在你需要cqlsh来与Cassandra数据库交互。这里会稍微有点曲折,因为它在cassandra下载的包中。因此在我们插入数据到cassandra中还需要做点变通 (1)从 http://www.python.org/download/releases/ 下载Python包。这里需注意一点。虽然python最新的版本是3x, 但是在这个版本上我们无法安装thrift库。 所以下载并 安装python2.7版本。 (2)从http://pypi.python.org/pypi/thrift下载Thrift库。 通过执行以下命令安装thrift模块。python setup.py install Step 4: 现在你可以安装cql模块,这个模块可以下你的cassandra下载包中找到。setup.py存在与 cassandra_home\pylib 中。 再次执行以下命令:python setup.py install Step 5: 执行命令 python cqlsh localhost 9160,(9160是端口,你需要改成你自己的sassandra端口), 然后可以启动cql命令工具。 以下是执行的example: CREATE KEYSPACE mykeyspace WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 }; CREATE TABLE users (user_id int PRIMARY KEY, fname text, lname text); INSERT INTO users (user_id, fname, lname) VALUES (1745, 'john', 'smith'); INSERT INTO users (user_id, fname, lname) VALUES (1744, 'john', 'doe'); INSERT INTO users (user_id, fname, lname) VALUES (1746, 'john', 'smith'); 首先我将根据官方文档,向你介绍conf目录下cassandra.yaml这个配置文件中几个重要的参数,无论是搭建集群环境,还是未来使用cqlsh的shell命令,这些参数都显得十分重要: cluster_name:集群名称,通常用于防止一个逻辑集群中的机器加入其他的集群,具有唯一标识性。 默认值:Test Cluster。 我的建议:在生产环境不要使用默认的集群名,以免未来在扩展多数据中心,多集群时引起命名冲突,造成不必要的麻烦。此外,在启动服务前提前修改好此参数,否则服务一旦启动,将围绕此集群名建立一系列的系统表,到时想更换集群名字只能删除所有系统表,很麻烦。 seed_provider:-parameters:-seeds:集群中的种子节点,被视为联系不同节点的主机地址。节点通过该列表的主机来找到对方,并学习集群环中的拓扑结构,通过Gossip相互沟通。 我的建议:种子实际上是一个逗号分隔的地址列表。如果你想要设置多个种子节点,你应该遵循这样的格式:Ex: “ip1,ip2,ip3”,在此处我填写 seeds:192.168.30.101。我仅设置一台主机。 listen_address: 通常用于通知其他节点通过此ip地址连接到你这台机器节点。 我的建议:不要将监听地址设置为0.0.0.0,这样做通常是错误,而是设置成具体的本机ip,如此处我设置为 listen_address: 192.168.30.101。 rpc_address: 此ip地址将绑定 Thrift RPC 服务,本地的传输服务也将使用此ip。 我的建议: 不要将监听地址设置为0.0.0.0或者localhost,这样做通常是错误,而是设置成具体的本机ip,如此处我设置为 rpc_address: 192.168.30.101。 data_file_directories: Cassandra通常在该磁盘目录下存储数据,进行均匀地分布数据, 这取决于你配置的压缩策略。 我的建议: 你可以设置成你想要的任何目录地址,但是我建议你采用默认的方式,Cassandra将自动加载到如下目录$CASSANDRA_HOME/data/data,方便管理。 commitlog_directory: 日志存放目录,通常用于记录写入数据的日志,当发生意外无法写入到SSTable时,可以使用commitlog恢复数据,防止丢失。 我的建议:你可以设置成你想要的任何目录地址,但是我建议你采用默认的方式,Cassandra将自动加载到如下目录$CASSANDRA_HOME/data/commitlog,方便管理。 saved_caches_directory: 缓存地址 我的建议: 你可以设置成你想要的任何目录地址,但是我建议你采用默认的方式,Cassandra将自动加载到如下目录$CASSANDRA_HOME/data/saved_caches,方便管理。 logback.xml: 通常用于系统日志输出的地址配置。 我的建议: 你可以设置成你想要的任何目录地址,但是我建议你采用默认的方式,Cassandra将自动加载到如下目录$CASSANDRA_HOME/logs目录下,方便管理。 本文转自大数据躺过的坑博客园博客,原文链接http://www.cnblogs.com/zlslch/p/8031548.html如需转载请自行联系原作者
1 什么是设计模式 设计模式是对在软件设计过程中重复出现的问题提出了一种比较好的解决方案。正如一位专家所说:设计模式是对程序设计人员经常遇到的设计问题的可再现的解决方案(The Smalltalk Companion)。GOF设计模式通常被认为是其他设计模式的基础,随着业务复杂度的增大,会不断涌现新的设计模式,而这些新的设计模式一般会以GOF模式理论为参照。 2 为什么要学习设计模式 从个人职业规划来考虑。一位软件开发工程师随着编码量的增加,开发经验的增加,软件理论理解的加深,会不由自主地想一些方法或者捷径,来提高自己的生产率,而不是面对重复的问题做相同的工作,当你有这种想法的时候,就需要开始学习设计模式,设计模式会给你一些比较好的解决方案,不但解决了问题也提升了自己的能力,同时也是迈向软件设计师和架构师的过度阶段。 从软件架构的角度来考虑。经济的快速发展造就了业务越来越复杂,那么如何使软件适应这种复杂的业务变化,在软件设计和架构时,适当地使用设计模式可以解决此问题,也要注意不要过度使用设计模式,否则会使系统变的更加复杂。设计模式也是代码重构的依据和工具,建议在代码的重构时,尽量融入设计模式。 3 设计模式原则 使用设计模式的根本原因是适用变化,提高代码复用率,使软件更具有可维护性和可扩展性。需要遵循以下几个原则:单一职责原色、开放封闭原则(Open Closed Principal)、依赖倒置原则、里氏代换原则。 3.1单一职责原则 就一个类而言,应该只有一个引起他变化的原因。如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会消弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破会。 3.2开放封闭原则 软件实体(类、模块、函数等)应该可以扩展,但不可以修改。也就是说对扩展是开放的,对修改是封闭的。一般来说,面对需求,对程序的改动是通过添加新代码进行的,而不是更改现有代码。 3.3依赖倒置原则 抽象不应该以来细节,细节应该依赖抽象,也就是提倡的“面对接口编程,而不是面对实现编程”。也可以这样理解:高层模块不应该依赖底层模块,两个都应该抽象;抽象不应该依赖细节,细节应该依赖抽象。 3.4里氏代换原则 子类必须能够替换掉他们的父类型。也就是说,在软件开发过程中,子类替换掉父类,程序的功能行为没有变化。只有当子类可以替换掉父类,软件单位的功能不受到影响时,父类才能真正被复用,而子类也可以在父类的基础上增加新的行为。 4 设计模式四个基本要素 设计模式使人们可以更加简单方便地复用成功的设计和体系结构,将已证实的技术表述成设计模式也会使新加入的系统开发者更加容易理解其设计思路。设计模式的基本要素包括模式名称、问题、解决方案和效果。 4.1模式名称 一个助记名称,用来描述设计模式、解决方案和效果。设计模式允许在较高的抽象层次上进行设计。基于一个模式词汇表,开发团队之间可以讨论模式并在编写文档时使用它们。模式名称可以帮助我们思考,便于团队成员交流设计思想及设计结果。找到合适的模式名称也是设计模式编目工作的难点之一。 4.2问题 问题主要描述在何时使用设计模式。它解释了设计问题和问题存在的前因后果、特定的设计问题和怎样用对象表示算法等。通常情况下,模式必须满足的一系列先决条件是问题。 4.3解决方案 解决方案描述了设计的组成成分、它们之间的相互关系及各自的职责和协作方式。因为模式就像一个模板,可应用于多种不同场合,所以解决方案并不描述一个特定具体的设计或实现,而是提供设计问题的抽象描述和怎样用一个具有一般意义的元素组合(类或对象组合)来解决这个问题。 4.4效果 描述了模式应用的效果及使用模式权衡的问题。尽管描述设计决策时,并不是总提到模式效果,但它们对于评价设计选择和理解使用模式的代价及优势具有重要意义。软件效果大多关注对时间和空间的衡量,它们也表述了语言和实现问题。因为复用是面向对象设计的要素之一,所以模式效果包括它对系统灵活性、扩充性或可移植性的影响,显式地列出这些效果对理解和评价这些模式很有帮助。 5 设计模式分类 设计模式主要分为创建性模式( Creational Patterns)、结构性模式(Structural Patterns)、行为性模式(Behavioral Patterns)。 5.1创建性模式( Creational Patterns) 5.1.1 Net设计模式实例之简单工厂模式(Simple Factory Pattern) 简单工厂模式(Simple Factory Pattern)的优点是,工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖 5.1.2 Net设计模式实例之抽象工厂模式(Abstract Factory Pattern) 抽象工厂模式(Abstract Factory Pattern),提供一个创建一系列相关或者相互依赖对象的接口,而无需制定他们的具体类。抽象工厂模式的典型应用就是,使用抽象工厂+反射+配置文件实现数据访问层程序 5.1.3 Net设计模式实例之单例模式( Singleton Pattern) 单例模式(Singleton Pattern),保证一个类只有一个实例,并提供一个访问它的全局访问点。单例模式因为Singleton封装它的唯一实例,它就可以严格地控制客户怎样访问它以及何时访问它。 5.1.4 Net设计模式实例之建造者模式(Builder Pattern) 建造者模式(Builder Pattern),将一个复杂对象的构建与它的表示分离,使的同样的构建过程可以创建不同的表示。建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式时适用的模式 5.1.5 Net设计模式实例之原型模式( Prototype Pattern) 原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。Specify the kind of objects to create using a prototypical instance, and create new objects by copying this prototype。 浅复制与深复制区别: 浅复制,被复制的所有变量都还有与原来对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。深复制,把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。 Net命名空间System提供了一个IConeable接口,此接口只有一个方法Clone(),只需要实现这个接口就可以实现原型模式(Prototype Pattern)了 5.2结构性模式(Structural Patterns) 5.2.1 Net设计模式实例之适配器模式(Adapter Pattern) 适配器模式,将一个类装换成客户期望的另外一个接口。Adapter模式统一了不兼容对象的接口,使的原本由于接口不兼容而不能工作的那些类可以一起工作。 5.2.2 Net设计模式实例之桥接模式( Bridge Pattern) 桥接模式(Bridge Pattern),将抽象部分与它的实现部分分离,使的抽象和实现都可以独立地变化。Decouple an abstraction from its implementation so that the two can vary independently.。 什么是聚合/组合: 聚合(Aggregation),当对象A被加入到对象B中,成为对象B的组成部分时,对象B和对象A之间为聚合关系。聚合是关联关系的一种,是较强的关联关系,强调的是整体与部分之间的关系。 5.2.3Net设计模式实例之组合模式(Composite Pattern) 组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。解决整合与部分可以被一致对待问题。 5.2.4 Net设计模式实例之装饰者模式(Decorator Pattern) 装饰模式,给一个对象动态添加额外职责,这些职责需要由用户决定加入的方式和时机。装饰模式提供了“即插即用”的方式,在运行期间决定何时增加何种功能。就增加功能来说,装饰模式比生成子类更加灵活。 5.2.5 Net设计模式实例之外观模式(Façade Pattern) 外观模式,为子系统的一组接口提供一个统一的界面,此模式定义了一个高层接口,这一个高层接口使的子系统更加容易使用。外观模式可以解决层结构分离、降低系统耦合度和为新旧系统交互提供接口功能。 5.2.6 Net设计模式实例之享元模式( Flyweight Pattern) 享元模式(Flyweight Pattern),运用共享技术有效支持大量细粒度的对象。Use sharing to support large numbers of fine-grained objects efficiently. 享元模式可以避免大量非常相似类的开销。在程序设计中有时需要生成大量细粒度的类实例来表示数据。如果发现这些实例除了几个参数外基本伤都是相同的,有时就能够受大幅度第减少需要实例化的类的数量。如果能把这些参数移到类实例外面,在方法调用时将他们传递进来,就可以通过共享大幅度地减少单个实例的数目。 享元对象的内部状态与外部状态: 内部状态,在享元对象的内部并且不会随环境改变而改变的共享部分。 外部状态,随环境改变而改变的,不可以共享的状态。 5.2.7 Net设计模式实例之代理模式(Proxy Pattern) 代理模式(Proxy Pattern)对其他对象提供一种代理以控制对这个对象的访问。 5.3行为性模式(Behavioral Patterns) Net设计模式实例之职责链模式(Chain Of Responsibility) 后期补此节 5.3.1Net设计模式实例之命令模式(Command Pattern) 命令模式(Command Pattern)将请求封装为一个对象,从而使你用不同的请求对客户进行参数化,对请求排队或纪录请求日志,以及支持可撤销的操作。当需要有撤销或者恢复操作时,可以考虑使用命令模式. 5.3.2Net设计模式实例之解释器模式(Interpreter Pattern) 解释器模式(Interpreter Pattern),给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象的语法树时,可以考虑使用解释器模式。 5.3.3 Net设计模式实例之迭代器模式(Iterator Pattern) 迭代器模式(Iterator Pattern),提供一种方法顺序访问一个聚合对象中元素,而不暴露改集合对象的内部表示。迭代器模式就是分离了集合对想的遍历行为,抽象出一个迭代器类来负责,这样即可以不暴露集合的内部机构,又可让外部代码透明地访问集合内部的数据. 5.3.4 Net设计模式实例之中介者模式(Mediator Pattern) 中介者模式(Mediator Pattern),定义一个中介对象来封装系列对象之间的交互。中介者使各个对象不需要显示地相互引用,从而使其耦合性松散,而且可以独立地改变他们之间的交互。中介者模式一般应用于一组对象以定义良好但是复杂的方法进行通信的场合,以及想定制一个分布在多个类中的行为,而不想生成太多的子类的场合. 5.3.5 Net设计模式实例之备忘录模式(Memento Pattern) 备忘录模式(Memento Pattern),在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以就该对象恢复到原先保存的状态。 当系统功能比较复杂,而且需要记录历史属性以便当需要时做恢复动作。Originator可以根据保存的Memento信息还原到前一状态。 5.3.6Net设计模式实例之观察者模式(Observer Pattern) 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化的时,会通知所有观察者对象,使他们能够自动更新自己。解决的是“当一个对象的改变需要同时改变其他对象的时候”问题。最后以股票实例进一步阐述了观察者模式。 5.3.7Net设计模式实例之状态模式(State Pattern) 状态模式(State Pattern),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。当一个对象行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了. Net设计模式实例之策略模式(Strategy Pattern) 后期补此节 5.3.8Net设计模式实例之模板方法模式(Template Mothed Pattern) 模板方法模式(Template Method Pattern),定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可以重定义算法的某些特定步骤。模板方法模式把不变行为搬移到超类,从而去除子类中的重复代码,实际上模板方法模式就是提供了一个代码复用平台。 要完成在某一细节上层次一致的一个过程或一系列步骤,但个别步骤在更详细的层次上实现不同时,可以使用模版方法模式解决问题。 5.3.9Net设计模式实例之访问者模式(Visitor Pattern) 访问者模式表示一个作用于某对象结构中的个元素操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 访问者模式的目的是要把处理从数据结构分离出来 6 设计模式总结 Net设计模式系列文章介绍了GOF 23个模式,从模式的设计理念、设计框架、框架的代码介绍了设计模式,并且每个模式配有模式实例,UML设计及其C#代码。使用的设计工具是EA:Enterprise Architect.主要参考的书籍有《Head First 设计模式》《大话设计模式》《Net与设计模式》《C# 3.0 Design Pattern》及其国外一些文章的实例,在此对这些书的作者感谢,在阅读此系列文章之前,建议大家先阅读《UML建模系列文章总结》 至此,Net设计模式实例系列文章已经写完,由于个人能力有限,不免有些问题阐述的不清楚或者不是非常正确,望高手指点。再此感谢 本文转自灵动生活博客园博客,原文链接:http://www.cnblogs.com/ywqu/archive/2010/03/15/1686015.html,如需转载请自行联系原作者
不多说,直接上干货! 说明: Anaconda2-5.0.0-Windows-x86_64.exe安装下来,默认的Python2.7 Anaconda3-4.2.0-Windows-x86_64.exe安装下来,默认的Python3.5 Anaconda3-5.0.0-Windows-x86_64.exe安装下来,默认的Python3.6 参考 全网最全最详细的Windows下安装Anaconda2 / Anaconda3(图文详解) 1、 以下是在Windows下Anaconda2里正确下载安装OpenCV(离线方式) 下载地址 因为python装的是Anaconda2版本,所以对应着选择,就安装 https://www.lfd.uci.edu/~gohlke/pythonlibs/ PS C:\Anaconda2\Lib\site-packages> pip install opencv_python-2.4.13.2-cp27-cp27m-win_amd64.whl Processing c:\anaconda2\lib\site-packages\opencv_python-2.4.13.2-cp27-cp27m-win_amd64.whl Installing collected packages: opencv-python Successfully installed opencv-python-2.4.13.2 PS C:\Anaconda2\Lib\site-packages> 测试一下,输python进入python,输入import cv2回车,不报错就说明安装配置成功了 PS C:\Anaconda2\Lib\site-packages> python Python 2.7.13 |Anaconda, Inc.| (default, Sep 19 2017, 08:25:59) [MSC v.1500 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> >>> import cv2 >>> 对于这种方式,我尝试了,是可以行得通的。 2、 以下是在Windows下Anaconda3里正确下载安装OpenCV(离线方式) 下载地址 因为python装的是Anaconda3版本,所以对应着选择,就安装 PS C:\Anaconda3\Lib\site-packages> pip install opencv_python-3.3.1-cp36-cp36m-win_amd64.whl opencv_python-3.3.1-cp36-cp36m-win_amd64.whl is not a supported wheel on this platform. PS C:\Anaconda3\Lib\site-packages> 如果还出现这个情况,则换个版本试试。这个很简单,尝试这个版本 PS C:\Anaconda3\Lib\site-packages> pip install opencv_python-3.3.0-cp36-cp36m-win_amd64.whl Processing c:\anaconda3\lib\site-packages\opencv_python-3.3.0-cp36-cp36m-win_amd64.whl Installing collected packages: opencv-python Successfully installed opencv-python-3.3.0 PS C:\Anaconda3\Lib\site-packages> 成功!这样的安装方式是没问题的。 import cv2成功。 3、以下是在Windows下Anaconda3里的envs里正确下载安装OpenCV(离线方式) PS C:\Anaconda3\envs\python35\Lib\site-packages> pip install opencv_python-3.3.0-cp36-cp36m-win_amd64.whl Requirement already satisfied: opencv-python==3.3.0 from file:///C:/Anaconda3/envs/python35/Lib/site-packages/opencv_python-3.3.0-cp36-cp36m-win_amd64.whl in c:\anaconda3\lib\site-packages PS C:\Anaconda3\envs\python35\Lib\site-packages> 一样的,因为这个envs环境是通过如下创建得到的,所以,是寄生在Anaconda3里。 这种方式,也是成功的。 如果大家中间有遇到如下的问题,则对应解决。 C:\Users\lenovo>python Python 3.6.2 |Anaconda custom (64-bit)| (default, Sep 19 2017, 08:03:39) [MSC v.1900 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> >>> import cv2 RuntimeError: module compiled against API version 0xb but this version of numpy is 0xa Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: numpy.core.multiarray failed to import >>> >>> import numpy >>> exit() C:\Users\lenovo> C:\Users\lenovo>pip install numpy --upgrade Exception: Traceback (most recent call last): File "C:\Anaconda3\lib\site-packages\pip\basecommand.py", line 215, in main status = self.run(options, args) File "C:\Anaconda3\lib\site-packages\pip\commands\install.py", line 335, in run wb.build(autobuilding=True) File "C:\Anaconda3\lib\site-packages\pip\wheel.py", line 749, in build self.requirement_set.prepare_files(self.finder) File "C:\Anaconda3\lib\site-packages\pip\req\req_set.py", line 380, in prepare_files ignore_dependencies=self.ignore_dependencies)) File "C:\Anaconda3\lib\site-packages\pip\req\req_set.py", line 487, in _prepare_file req_to_install, finder) File "C:\Anaconda3\lib\site-packages\pip\req\req_set.py", line 428, in _check_skip_installed req_to_install, upgrade_allowed) File "C:\Anaconda3\lib\site-packages\pip\index.py", line 465, in find_requirement all_candidates = self.find_all_candidates(req.name) File "C:\Anaconda3\lib\site-packages\pip\index.py", line 423, in find_all_candidates for page in self._get_pages(url_locations, project_name): File "C:\Anaconda3\lib\site-packages\pip\index.py", line 568, in _get_pages page = self._get_page(location) File "C:\Anaconda3\lib\site-packages\pip\index.py", line 683, in _get_page return HTMLPage.get_page(link, session=self.session) File "C:\Anaconda3\lib\site-packages\pip\index.py", line 811, in get_page inst = cls(resp.content, resp.url, resp.headers) File "C:\Anaconda3\lib\site-packages\pip\index.py", line 731, in __init__ namespaceHTMLElements=False, TypeError: parse() got an unexpected keyword argument 'transport_encoding' C:\Users\lenovo> 如果运行下来,还是没得到解决,则 再尝试下, 问题出现的原因是numpy的版本较高,不能与opencv2兼容 解决办法: pip install -U numpy 即可将numpy恢复到合适的版本(这里为1.9.2) 再 import cv2 就不会出现上面的问题了。 成功! 有时候,你可能得卸载Anaconda3里已经安装好了的opencv,再来安装。(为什么呢?是因为你可能没看仔细,下错版本了) 成功! 同样,对于如果你是Anaconda3-4.2.0-Windows-x86_64.exe安装下来,默认的Python3.5,则如下 成功! 4、以下是在Windows下Anaconda3里正确下载安装OpenCV(在线方式)(注意这里有坑,一定要按照我的来) (C:\Anaconda3) C:\Users\lenovo>pip install opencv-python Collecting opencv-python Cache entry deserialization failed, entry ignored Downloading opencv_python-3.3.0.10-cp35-cp35m-win_amd64.whl (39.7MB) 100% |████████████████████████████████| 39.7MB 25kB/s Requirement already satisfied (use --upgrade to upgrade): numpy>=1.11.1 in c:\anaconda3\lib\site-packages (from opencv-python) Installing collected packages: opencv-python Successfully installed opencv-python-3.3.0.10 You are using pip version 8.1.2, however version 9.0.1 is available. You should consider upgrading via the 'python -m pip install --upgrade pip' command. (C:\Anaconda3) C:\Users\lenovo> 验证下,出现如下的错误 (C:\Anaconda3) C:\Users\lenovo>pip install opencv-python Collecting opencv-python Cache entry deserialization failed, entry ignored Downloading opencv_python-3.3.0.10-cp35-cp35m-win_amd64.whl (39.7MB) 100% |████████████████████████████████| 39.7MB 25kB/s Requirement already satisfied (use --upgrade to upgrade): numpy>=1.11.1 in c:\anaconda3\lib\site-packages (from opencv-python) Installing collected packages: opencv-python Successfully installed opencv-python-3.3.0.10 You are using pip version 8.1.2, however version 9.0.1 is available. You should consider upgrading via the 'python -m pip install --upgrade pip' command. (C:\Anaconda3) C:\Users\lenovo> (C:\Anaconda3) C:\Users\lenovo>python Python 3.5.2 |Anaconda 4.2.0 (64-bit)| (default, Jul 5 2016, 11:41:13) [MSC v.1900 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> >>> import cv3 Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named 'cv3' >>> import cv2 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Anaconda3\lib\site-packages\cv2\__init__.py", line 9, in <module> from .cv2 import * ImportError: DLL load failed: 找不到指定的模块。 >>> 尝试解决 >>> import cv2 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Anaconda3\lib\site-packages\cv2\__init__.py", line 9, in <module> from .cv2 import * ImportError: DLL load failed: 找不到指定的模块。 >>> pip install -U numpy File "<stdin>", line 1 pip install -U numpy ^ SyntaxError: invalid syntax >>> exit() (C:\Anaconda3) C:\Users\lenovo>pip install -U numpy Cache entry deserialization failed, entry ignored Collecting numpy Downloading numpy-1.13.3-cp35-none-win_amd64.whl (13.1MB) 100% |████████████████████████████████| 13.1MB 74kB/s Installing collected packages: numpy Found existing installation: numpy 1.11.1 Uninstalling numpy-1.11.1: Successfully uninstalled numpy-1.11.1 Successfully installed numpy-1.13.3 You are using pip version 8.1.2, however version 9.0.1 is available. You should consider upgrading via the 'python -m pip install --upgrade pip' command. (C:\Anaconda3) C:\Users\lenovo> (C:\Anaconda3) C:\Users\lenovo> 可以看到,如果你是直接这么来安装,是错误的。为什么呢?按照我的来,先卸载吧。 需要源文件安装,通过,pip一般都是失败的(经过验证,需要处理下) 于是,我把它给卸载了,带大家来重新做一遍。 解决办法: https://github.com/skvark/opencv-python/issues/36 什么意思,很简单。 (1)下载安装 Visual C++ Redistributable for Visual Studio 2015 不难,别嫌麻烦。 (2) 把下载的python3.dll放到你所安装Anaconda3的目录下即可。 我的是这样的。 然后,再尝试pip install opencv-python执行完后,再import cv2就可以成功了 成功! 5、也可以直接在Pycharm里搜索并安装Opencv 这个不多赘述 总结 很多人写的对于OpenCV都是冰山一角,其实没有大家想的那么复杂,只是没有多尝试罢了。 无论是Python2还是Python3系列,都可以安装,且离线和在线安装成功。 提醒的是,注意对应自己的版本去安装。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/8059715.html,如需转载请自行联系原作者
不多说,直接上干货! Theano的安装教程目前网上一搜很多,前几天折腾了好久,终于安装成功了Anaconda3(Python3)的Theano,嗯~发博客总结并分享下经验教训吧。 渣电脑,显卡用的是六代Intel家自家的核心显卡HD530,并没有办法用CUDA加速,所以CUDA的安装和配置,我就直接略过不表。 第一步:查看目标磁盘空间 建议直接默认地址,C盘(系统盘)的空间至少要1.8G,如果低于这个值,Anaconda无法进行下一步安装 第二步:安装Anaconda3 我是全部默认安装啊,安装的文件夹地址是C:\Users\XX(用户名~)\Anaconda3,这个是单一用户安装。单一用户安装的好处是,后面安装MinGW和Theano的时候无需请求最高权限。注意:一定要勾选将Anaconda加入到环境变量!!!!!! 一路Next…… 安装完后检查下是不是把Anaconda成功加入了系统变量 第三步:安装MinGW和libpython 开始——>运行——>CMD——>输入“conda install mingw libpython”——>y——>坐等——>over 安装完后,看看Anaconda安装文件夹里面有没有MinGW文件夹 MinGW文件夹路径示例:"C:\Users\XX\Anaconda3\MinGW" 我这里是用在"C:\Anaconda3\MinGW" 第四步:环境配置 以前很多教程都要求要添加环境路径,由于前面已经添加了Anaconda的环境路径,所以这个可以省略 还需要在CMD的home目录中新建 .theanorc.txt 文件(注意:theanorc前后都有“.”!!!!) CMD的home目录就是打开CMD之后命令行的当前目录,实在不知道,后面有参考博客可以参考下 .theanorc.txt 文件内容如下 [blas] ldflags= [gcc] cxxflags=-IC:\Anaconda3\MinGW(更改为MinGW的所在的文件路径!!!) 完成后,建议还是重启下吧…… 第五步:安装Theano 开始——>运行——>CMD——>输入“pip install theano”——>坐等——>over 第六步:测试Theano是否成功安装 打开IPython/Spider,输入: import theano theano.test() 等待的时间较长,没有error就好…… 另外,关于blas加速的问题,以上设置并没能实现BLAS加速 搜索了下,发现知乎里面SCP-173指出 “anaconda已经内置了mkl,这个性能只会比openblas效果好,所以放心使用吧,之后的nvcc才是坑” 知乎链接:https://www.zhihu.com/question/44266587 嗯~不明觉厉~~ 第一次安装出现过的问题及解决方法: “不论是用pip list还是import theano,都出现module configparser has no attribute safeconfigparser错误” 解决链接 : https://www.zhihu.com/question/52950325/answer/135344877 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/8064029.html,如需转载请自行联系原作者
不多说,直接上干货! 说明: Anaconda2-5.0.0-Windows-x86_64.exe安装下来,默认的Python2.7 Anaconda3-4.2.0-Windows-x86_64.exe安装下来,默认的Python3.5 Anaconda3-5.0.0-Windows-x86_64.exe安装下来,默认的Python3.6 为什么会罗列出这三个版本,是因为,满足不同的人的需求,有些组件和书籍资料还没有完全过度到Python3。 1、Anaconda2 / Anaconda3的下载 Anaconda 官网下载地址:https://www.continuum.io/downloads 目前最新版本是 python 3.6,默认下载也是 Python 3.6, 我使用的是 Python 3.5 版本,这里使用Anaconda3-4.2.0-Windows-x86_64.exe版本,因为它默认使用的是 Python 3.5。 官方下载地址:https://repo.continuum.io/archive/, 百度网盘下载地址:http://pan.baidu.com/s/1nvT0sch 密码:i40x 当然,也可以在官网下载最新版本的 Anaconda3,然后根据自己需要设置成 python 3.5。 2、Anaconda2-5.0.0-Windows-x86_64.exe的安装 如下,步骤是一样的,不多赘述。 3、Anaconda3-4.2.0-Windows-x86_64.exe的安装 安装较为简单,基本都是下一步,为了避免不必要的麻烦,最后默认安装路径,具体安装过程为: 双击安装文件,启动安装程序 如果系统只有一个用户选择默认的第一个即可,如果有多个用户而且都要用到 Anaconda ,则选择第二个选项。 但是,根据个人经验而言,比如在Anaconda里安装Theano这样的组件,最好是在Anaconda里就选择默认的只有一个用户是最好的,免得自己各种后续小问题浪费时间。再者,你电脑那么多用户,你想干嘛(少数人特殊罢了)。 两个默认就好,第一个是加入环境变量,第二个是默认使用 Python 3.5。 安装需要一段时间,等待安装完成即可。 到这里就安装完成了,可以将“Learn more about Aanaconda Cloud”前的对号去掉,然后点击“Finish”即可。 4、Anaconda3-5.0.0-Windows-x86_64.exe的安装 不多赘述,一样的 5、Anaconda2的使用 6、Anaconda3的使用 安装完成后可以点击系统左下角的 Windows 图标找到 Anaconda3 文件夹,查看所包含的内容。 7、Anaconda2和Anaconda3在Windows环境下灵活切换 点击“Jupyter Notebook”即可启动 notebook 这里不多赘述。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/8064108.html如需转载请自行联系原作者
不多说,直接上干货! 问题详情 点击 出现Anaconda-Navigator启动后闪退的现象。 或者 装过一次anaconda,貌似按了一个更新的键就打不开了。navigator这个打不开,会停留在图标然后闪退。其余的都可以打开。 File "C:\Program Files\Anaconda3\lib\site-packages\anaconda_navigator\widgets\main_window.py", line 355, in process_application_info packages, apps = output TypeError: 'NoneType' object is not iterable 用cmd打开navigator,会出现以上问题。找到了所说的文件,可是不知道要改什么。 下面是提示错误的地方: def process_application_info(self, worker, output, error): """Create application projects.""" if error: logger.error(str(error)) packages, apps = output processed_apps = self.api.process_apps(apps) 解决方法(不推荐) 注意:网上有些人写的博客资料,说(不建议这么干,别动不动就更新,会对你使用很大影响) 在安装好anaconda navigator 后,点击打开anaconda navigator 会出现闪退现象,即出现下图就闪退。解决方案是: 打开你电脑的终端,在Anaconda Prompt中输入: conda upgrade --all 同时,以下这样做,也不建议 1.打开Anaconda Prompt 2.输入 conda install -c anaconda anaconda-navigator=1.6.2 3.更新完成后就可以了 解决方法(推荐) 第一步:使用管理员运行:conda prompt 第二步:执行命令 conda update anaconda-navigator (C:\Anaconda3) C:\Users\lenovo> conda update anaconda-navigator Fetching package metadata ......... Solving package specifications: .......... Package plan for installation in environment C:\Anaconda3: The following packages will be downloaded: package | build ---------------------------|----------------- vc-14 | 0 703 B chardet-3.0.4 | py35_0 202 KB qtpy-1.3.1 | py35_0 41 KB requests-2.14.2 | py35_0 705 KB anaconda-client-1.6.3 | py35_0 184 KB anaconda-project-0.6.0 | py35_0 223 KB pyopenssl-16.2.0 | py35_0 70 KB anaconda-navigator-1.6.4 | py35_0 3.9 MB conda-4.3.30 | py35hec795fb_0 541 KB ------------------------------------------------------------ Total: 5.8 MB The following NEW packages will be INSTALLED: anaconda-project: 0.6.0-py35_0 chardet: 3.0.4-py35_0 conda-env: 2.6.0-0 vc: 14-0 The following packages will be UPDATED: anaconda-client: 1.5.1-py35_0 --> 1.6.3-py35_0 anaconda-navigator: 1.3.1-py35_0 --> 1.6.4-py35_0 conda: 4.2.9-py35_0 --> 4.3.30-py35hec795fb_0 pyopenssl: 16.0.0-py35_0 --> 16.2.0-py35_0 qtpy: 1.1.2-py35_0 --> 1.3.1-py35_0 requests: 2.11.1-py35_0 --> 2.14.2-py35_0 Proceed ([y]/n)? y Fetching packages ... vc-14-0.tar.bz 100% |###############################| Time: 0:00:00 350.65 kB/s chardet-3.0.4- 100% |###############################| Time: 0:00:00 275.41 kB/s qtpy-1.3.1-py3 100% |###############################| Time: 0:00:00 103.41 kB/s requests-2.14. 100% |###############################| Time: 0:00:01 563.00 kB/s anaconda-clien 100% |###############################| Time: 0:00:00 257.49 kB/s anaconda-proje 100% |###############################| Time: 0:00:00 246.00 kB/s pyopenssl-16.2 100% |###############################| Time: 0:00:00 175.56 kB/s anaconda-navig 100% |###############################| Time: 0:00:07 510.25 kB/s conda-4.3.30-p 100% |###############################| Time: 0:00:01 459.78 kB/s Extracting packages ... [ COMPLETE ]|##################################################| 100% Unlinking packages ... INFO menuinst_win32:__init__(182): Menu: name: 'Anaconda${PY_VER} ${PLATFORM}', prefix: 'C:\Anaconda3', env_name: 'None', mode: 'None', used_mode: 'user' [ COMPLETE ]|##################################################| 100% Linking packages ... INFO menuinst_win32:__init__(182): Menu: name: 'Anaconda${PY_VER} ${PLATFORM}', prefix: 'C:\Anaconda3', env_name: 'None', mode: 'None', used_mode: 'user' [ COMPLETE ]|##################################################| 100% (C:\Anaconda3) C:\Users\lenovo> 第三步:执行anaconda-navigator --reset (C:\Anaconda3) C:\Users\lenovo>anaconda-navigator --reset Anaconda Navigator configuration reset... Anaconda Navigator configuration reset successful! (C:\Anaconda3) C:\Users\lenovo> 第四步:执行conda update anaconda-client (C:\Anaconda3) C:\Users\lenovo>conda update anaconda-client Fetching package metadata ............. Solving package specifications: . Package plan for installation in environment C:\Anaconda3: The following packages will be UPDATED: anaconda-client: 1.6.3-py35_0 --> 1.6.6-py35h690133a_0 conda: 4.3.30-py35hec795fb_0 --> 4.3.31-py35_0 conda-env: 2.6.0-0 --> 2.6.0-h36134e3_1 Proceed ([y]/n)? y conda-env-2.6. 100% |###############################| Time: 0:00:00 316.26 kB/s anaconda-clien 100% |###############################| Time: 0:00:00 251.02 kB/s conda-4.3.31-p 100% |###############################| Time: 0:00:01 473.96 kB/s (C:\Anaconda3) C:\Users\lenovo> 第五步:执行conda update -f anaconda-client (C:\Anaconda3) C:\Users\lenovo>conda update -f anaconda-client Fetching package metadata ............. Solving package specifications: . Package plan for installation in environment C:\Anaconda3: The following NEW packages will be INSTALLED: anaconda-client: 1.6.6-py35h690133a_0 Proceed ([y]/n)? y (C:\Anaconda3) C:\Users\lenovo> 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/8066662.html,如需转载请自行联系原作者
不多说,直接上干货! Git和TortoiseGit的区别: TortoiseGit的安装和使用依赖Git。 Git有且只有一个,就是linux最初创建的那个叫做Git的程序。现在的维护者的名字我懒得去查了。 最初的Git,只能运行在*nix系统上,然后,有人为它做了windows兼容的修改,Git for windows的具体维护工作应该是德国的一家公司的几个人在负责,没错,就是我们看到的那个msysGit,一个基于windows上虚拟unix环境mGw的Git。早期还有一个单独的windows Git的fork,现在已经不存在了。而msysGit本身,也是Git官方维护的版本,它的release是跟着Git主版本走的,但是因为有一些windows特有的修改不便merGe到主干,所以,现在还是有少量单独的修改是由msysGit的维护小组在管理负责的。这种情况将来会不会有所改善我不好说,但从这几年的情况来说,msysGit的修改是在一点一点的合并到主干的,因此,也许将来我们看到msysGit,有可能就仅仅只是一个mGw + Git的合并安装包而已了,但就现在来说,msysGit是跟着主干Git走的一个官方fork。 无论Github for windows,还是TorToiseGit,他们的底下都是依赖msysGit的,TorToiseGit为了提高性能,似乎在将内部实现从调用Git的cmd命令转移到一个Gitlib的dll上去,这个Gitlib的dll的历史渊源我不是很清楚,但应该跟msysGit脱不了关系,但即使如此,TorToiseGit现在仍然还是需要你安装msysGit才能正常动作的,因为它也还没有把所有的内部调用都替换掉,就现在来说,msysGit仍然是TorToiseGit的基础。 至于Github for windows,我没有用过,但从我看到过的资料来说,它其实是内置了一个msysGit的,你所有的操作,其实不过是Github for windows的Gui界面把你的操作翻译成命令行调用参数并调用Git的命令行程序而已,就是那个msysGit里面的Git.exe。 所以,Git本身就是Git,然后Github for windows和TorToiseGit都是Git的一个Gui包装。使用TorToiseGit,你需要单独下载msysGit安装,使用Github for windows,可以直接使用内置的msysGit而无须单独下载安装。 本文转自大数据躺过的坑博客园博客,原文链接://www.cnblogs.com/zlslch/p/7986039.html,如需转载请自行联系原作者
前面博客 Git学习系列之Git基本操作推送项目(图文详解) 当然,如果多人协作,或者多个客户端进行修改,那么我们还要拉取(Pull ... )别人推送到在线仓库的内容下来。 大神们是不推荐使用 pull 命令进行拉取的, 因为封装了细节(git pull == git fetch + git merge)。 对于这群更喜欢用命令行的神们来说, 一切在掌控之中是一种强迫症!!!(开个玩笑, 其实项目成员复杂,约定不好以后,pull 确实会有很多问题,会坑人。) 常规使用,我们执行 git pull 即可: F:\GIT_ALL\LispGentleIntro>git pull Already up-to-date. 当然,因为没有其他文件被修改,所以直接提示 已经更新到最新。 常规操作就这些,需要注意的是,和使用SVN的好习惯一样,你在修改本地内容之前,最好先 pull 一下,减少冲突的可能。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/7987068.html如需转载请自行联系原作者
数据类型 JavaScript 是 弱类型 语言,但并不是没有类型,JavaScript可以识别下面 7 种不同类型的值: 基本数据类型 Boolean Number String null undefined Symbol Object Array RegExp Date Math ... 可以使用 typeof 判断数据类型,操作符返回一个字符串,但并非返回的所有结果都符合预期 typeof false // "boolean" typeof .2 // "number" typeof NaN // "number" typeof '' // "string" typeof undefined // "undefined" typeof Symbol() // "symbol" typeof new Date() // "object" typeof [] // "object" typeof alert // "function" typeof null // "object" typeof not_defined_var // "undefined" 变量 在应用程序中,使用变量来来为值命名。变量的名称称为 identifiers 声明 使用关键字 var :函数作用域 使用关键字 let :块作用域 (block scope local variable) 直接使用:全局作用域 var global_var = 1; function fn () { var fn_var = 2; if(fn_var > 10){ let block_var = 3; global_var2 = 4; } } 只声明不赋值,变量的默认值是 undefined const 关键字可以声明不可变变量,同样为块作用域。对不可变的理解在对象上的理解需要注意 const num = 1; const obj = { prop: 'value' }; num = 2; // Uncaught TypeError: Assignment to constant variable. obj['prop'] = 'value2'; obj = []; // Uncaught TypeError: Assignment to constant variable. 变量提升 JavaScript中可以引用稍后声明的变量,而不会引发异,这一概念称为变量声明提升(hoisting) console.log(a); // undefined var a = 2; 等同于 var a; console.log(a); a = 2; 函数 一个函数就是一个可以被外部代码调用(或者函数本身递归调用)的 子程序 定义函数 函数声明 函数表达式 Function 构造函数 箭头函数 function fn(){} var fn = function(){} var fn = new Function(arg1, arg2, ... argN, funcBody) var fn = (param) => {} arguments arguments: 一个包含了传递给当前执行函数参数的类似于数组的对象 arguments.length: 传给函数的参数的数目 arguments.caller: 调用当前执行函数的函数 arguments.callee: 当前正在执行的函数 function foo() { return arguments; } foo(1, 2, 3); // Arguments[3] // { "0": 1, "1": 2, "2": 3 } rest function foo(...args) { return args; } foo(1, 2, 3); // Array[3] // [1, 2, 3] function fn(a, b, ...args){ return args; } fn(1, 2, 3, 4, 5); // Array[3] // [3, 4, 5] default 函数的参数可以在定义的时候约定默认值 function fn (a = 2, b = 3) { return a + b; } fn(2, 3); // 5 fn(2); // 5 fn(); // 5 对象 JavaScript 中对象是可变 键控集合 (keyed collections) 定义对象 字面量 构造函数 var obj = { prop: 'value', fn: function(){} }; var date = new Date(); 构造函数 构造函数和普通函数并没有区别,使用 new 关键字调用就是构造函数,使用构造函数可以 实例化 一个对象 函数的返回值有两种可能 显式调用 return 返回 return 后表达式的求值 没有调用 return 返回 undefined function People(name, age) { this.name = name; this.age = age; } var people = new People('Byron', 26); 构造函数返回值 没有返回值 简单数据类型 对象类型 前两种情况构造函数返回构造对象的实例,实例化对象正是利用的这个特性 第三种构造函数和普通函数表现一致,返回 return 后表达式的结果 prototype 每个函数都有一个 prototype 的对象属性,对象内有一个 constructor 属性,默认指向函数本身 每个对象都有一个 __proto__ 的属性,属相指向其父类型的 prototype function Person(name) { this.name = name; } Person.prototype.print = function () { console.log(this.name); }; var p1 = new Person('Byron'); var p2 = new Person('Casper'); p1.print(); p2.print(); this 和作用域 作用域可以通俗的理解 我是谁 我有哪些马仔 其中我是谁的回答就是 this 马仔就是我的局部变量 this 场景 普通函数 严格模式:undefined 非严格模式: 全局对象 Node: global 浏览器: window 构造函数:对象的实例 对象方法:对象本身 call & apply fn.call(context, arg1, arg2, …, argn) fn.apply(context, args) function isNumber(obj) { return Object.prototype.toString.call(obj) === '[object Number]'; } Function.prototype.bind bind 返回一个新函数,函数的作用域为 bind 参数 function fn() { this.i = 0; setInterval(function () { console.log(this.i++); }.bind(this), 500) } fn(); () => {} 箭头函数是 ES6 提供的新特性,是简写的 函数表达式,拥有词法作用域和 this 值 function fn() { this.i = 0; setInterval(() => { console.log(this.i++); }, 500) } fn(); 继承 在 JavaScript 的场景,继承有两个目标,子类需要得到父类的: 对象的属性 对象的方法 function inherits(child, parent) { var _proptotype = Object.create(parent.prototype); _proptotype.constructor = child.prototype.constructor; child.prototype = _proptotype; } function People(name, age) { this.name = name; this.age = age; } People.prototype.getName = function () { return this.name; } function English(name, age, language) { People.call(this, name, age); this.language = language; } inherits(English, People); English.prototype.introduce = function () { console.log('Hi, I am ' + this.getName()); console.log('I speak ' + this.language); } function Chinese(name, age, language) { People.call(this, name, age); this.language = language; } inherits(Chinese, People); Chinese.prototype.introduce = function () { console.log('你好,我是' + this.getName()); console.log('我说' + this.language); } var en = new English('Byron', 26, 'English'); var cn = new Chinese('色拉油', 27, '汉语'); en.introduce(); cn.introduce(); ES6 class 与继承 "use strict"; class People{ constructor(name, age){ this.name = name; this.age = age; } getName(){ return this.name; } } class English extends People{ constructor(name, age, language){ super(name, age); this.language = language; } introduce(){ console.log('Hi, I am ' + this.getName()); console.log('I speak ' + this.language); } } let en = new English('Byron', 26, 'English'); en.introduce(); 语法 label statement loop: for (var i = 0; i < 10; i++) { for (var j = 0; j < 5; j++) { console.log(j); if (j === 1) { break loop; } } } console.log(i); 语句与表达式 var x = { a:1 }; { a:1 } { a:1, b:2 } 立即执行函数 ( function() {}() ); ( function() {} )(); [ function() {}() ]; ~ function() {}(); ! function() {}(); + function() {}(); - function() {}(); delete function() {}(); typeof function() {}(); void function() {}(); new function() {}(); new function() {}; var f = function() {}(); 1, function() {}(); 1 ^ function() {}(); 1 > function() {}(); 高阶函数 高阶函数是把函数当做参数或者返回值是函数的函数 回调函数 [1, 2, 3, 4].forEach(function(item){ console.log(item); }); 闭包 闭包由两部分组成 函数 环境:函数创建时作用域内的局部变量 function makeCounter(init) { var init = init || 0; return function(){ return ++init; } } var counter = makeCounter(10); console.log(counter()); console.log(counter()); 典型错误 for (var i = 0; i < doms.length; i++) { doms.eq(i).on('click', function (ev) { console.log(i); }); } for (var i = 0; i < doms.length; i++) { (function (i) { doms.eq(i).on('click', function (ev) { console.log(i); }); })(i); } 惰性函数 function eventBinderGenerator() { if (window.addEventListener) { return function (element, type, handler) { element.addEventListener(type, hanlder, false); } } else { return function (element, type, handler) { element.attachEvent('on' + type, handler.bind(element, window.event)); } } } var addEvent = eventBinderGenerator(); 柯里化 一种允许使用部分参数生成函数的方式 function isType(type) { return function(obj){ return Object.prototype.toString.call(obj) === '[object '+ type +']'; } } var isNumber = isType('Number'); console.log(isNumber(1)); console.log(isNumber('s')); var isArray = isType('Array'); console.log(isArray(1)); console.log(isArray([1, 2, 3])); function f(n) { return n * n; } function g(n) { return n * 2; } console.log(f(g(5))); function pipe(f, g) { return function () { return f.call(null, g.apply(null, arguments)); } } var fn = pipe(f, g); console.log(fn(5)); 尾递归 尾调用是指某个函数的最后一步是调用另一个函数 函数调用自身,称为递归 如果尾调用自身,就称为尾递归 递归很容易发生"栈溢出"错误(stack overflow) function factorial(n) { if (n === 1) return 1; return n * factorial(n - 1); } factorial(5) // 120 但对于尾递归来说,由于只存在一个调用记录,所以永远不会发生"栈溢出"错误 function factorial(n, total) { if (n === 1) return total; return factorial(n - 1, n * total); } factorial(5, 1) // 120 柯里化减少参数 function currying(fn, n) { return function (m) { return fn.call(this, m, n); }; } function tailFactorial(n, total) { if (n === 1) return total; return tailFactorial(n - 1, n * total); } const factorial = currying(tailFactorial, 1); factorial(5) // 120 反柯里化 Function.prototype.uncurry = function () { return this.call.bind(this); }; push 通用化 var push = Array.prototype.push.uncurry(); var arr = []; push(arr, 1); push(arr, 2); push(arr, 3); console.log(arr);,如需转载请自行联系原作者
Scalable IO in Java http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf 基本上所有的网络处理程序都有以下基本的处理过程: Read request Decode request Process service Encode reply Send reply Classic Service Designs 简单的代码实现: class Server implements Runnable { public void run() { try { ServerSocket ss = new ServerSocket(PORT); while (!Thread.interrupted()) new Thread(new Handler(ss.accept())).start(); //创建新线程来handle // or, single-threaded, or a thread pool } catch (IOException ex) { /* ... */ } } static class Handler implements Runnable { final Socket socket; Handler(Socket s) { socket = s; } public void run() { try { byte[] input = new byte[MAX_INPUT]; socket.getInputStream().read(input); byte[] output = process(input); socket.getOutputStream().write(output); } catch (IOException ex) { /* ... */ } } private byte[] process(byte[] cmd) { /* ... */ } } } 对于每一个请求都分发给一个线程,每个线程中都独自处理上面的流程。 这种模型由于IO在阻塞时会一直等待,因此在用户负载增加时,性能下降的非常快。 server导致阻塞的原因: 1、serversocket的accept方法,阻塞等待client连接,直到client连接成功。 2、线程从socket inputstream读入数据,会进入阻塞状态,直到全部数据读完。 3、线程向socket outputstream写入数据,会阻塞直到全部数据写完。 client导致阻塞的原因: 1、client建立连接时会阻塞,直到连接成功。 2、线程从socket输入流读入数据,如果没有足够数据读完会进入阻塞状态,直到有数据或者读到输入流末尾。 3、线程从socket输出流写入数据,直到输出所有数据。 4、socket.setsolinger()设置socket的延迟时间,当socket关闭时,会进入阻塞状态,直到全部数据都发送完或者超时。 改进:采用基于事件驱动的设计,当有事件触发时,才会调用处理器进行数据处理。 Basic Reactor Design 代码实现: class Reactor implements Runnable { final Selector selector; final ServerSocketChannel serverSocket; Reactor(int port) throws IOException { //Reactor初始化 selector = Selector.open(); serverSocket = ServerSocketChannel.open(); serverSocket.socket().bind(new InetSocketAddress(port)); serverSocket.configureBlocking(false); //非阻塞 SelectionKey sk = serverSocket.register(selector, SelectionKey.OP_ACCEPT); //分步处理,第一步,接收accept事件 sk.attach(new Acceptor()); //attach callback object, Acceptor } public void run() { try { while (!Thread.interrupted()) { selector.select(); Set selected = selector.selectedKeys(); Iterator it = selected.iterator(); while (it.hasNext()) dispatch((SelectionKey)(it.next()); //Reactor负责dispatch收到的事件 selected.clear(); } } catch (IOException ex) { /* ... */ } } void dispatch(SelectionKey k) { Runnable r = (Runnable)(k.attachment()); //调用之前注册的callback对象 if (r != null) r.run(); } class Acceptor implements Runnable { // inner public void run() { try { SocketChannel c = serverSocket.accept(); if (c != null) new Handler(selector, c); } catch(IOException ex) { /* ... */ } } } } final class Handler implements Runnable { final SocketChannel socket; final SelectionKey sk; ByteBuffer input = ByteBuffer.allocate(MAXIN); ByteBuffer output = ByteBuffer.allocate(MAXOUT); static final int READING = 0, SENDING = 1; int state = READING; Handler(Selector sel, SocketChannel c) throws IOException { socket = c; c.configureBlocking(false); // Optionally try first read now sk = socket.register(sel, 0); sk.attach(this); //将Handler作为callback对象 sk.interestOps(SelectionKey.OP_READ); //第二步,接收Read事件 sel.wakeup(); } boolean inputIsComplete() { /* ... */ } boolean outputIsComplete() { /* ... */ } void process() { /* ... */ } public void run() { try { if (state == READING) read(); else if (state == SENDING) send(); } catch (IOException ex) { /* ... */ } } void read() throws IOException { socket.read(input); if (inputIsComplete()) { process(); state = SENDING; // Normally also do first write now sk.interestOps(SelectionKey.OP_WRITE); //第三步,接收write事件 } } void send() throws IOException { socket.write(output); if (outputIsComplete()) sk.cancel(); //write完就结束了, 关闭select key } } //上面 的实现用Handler来同时处理Read和Write事件, 所以里面出现状态判断 //我们可以用State-Object pattern来更优雅的实现 class Handler { // ... public void run() { // initial state is reader socket.read(input); if (inputIsComplete()) { process(); sk.attach(new Sender()); //状态迁移, Read后变成write, 用Sender作为新的callback对象 sk.interest(SelectionKey.OP_WRITE); sk.selector().wakeup(); } } class Sender implements Runnable { public void run(){ // ... socket.write(output); if (outputIsComplete()) sk.cancel(); } } } 这里用到了Reactor模式。 关于Reactor模式的一些概念: Reactor:负责响应IO事件,当检测到一个新的事件,将其发送给相应的Handler去处理。 Handler:负责处理非阻塞的行为,标识系统管理的资源;同时将handler与事件绑定。 Reactor为单个线程,需要处理accept连接,同时发送请求到处理器中。 由于只有单个线程,所以处理器中的业务需要能够快速处理完。 改进:使用多线程处理业务逻辑。 Worker Thread Pools 参考代码: class Handler implements Runnable { // uses util.concurrent thread pool static PooledExecutor pool = new PooledExecutor(...); static final int PROCESSING = 3; // ... synchronized void read() { // ... socket.read(input); if (inputIsComplete()) { state = PROCESSING; pool.execute(new Processer()); //使用线程pool异步执行 } } synchronized void processAndHandOff() { process(); state = SENDING; // or rebind attachment sk.interest(SelectionKey.OP_WRITE); //process完,开始等待write事件 } class Processer implements Runnable { public void run() { processAndHandOff(); } } } 将处理器的执行放入线程池,多线程进行业务处理。但Reactor仍为单个线程。 继续改进:对于多个CPU的机器,为充分利用系统资源,将Reactor拆分为两部分。 Using Multiple Reactors 参考代码: Selector[] selectors; //subReactors集合, 一个selector代表一个subReactor int next = 0; class Acceptor { // ... public synchronized void run() { ... Socket connection = serverSocket.accept(); //主selector负责accept if (connection != null) new Handler(selectors[next], connection); //选个subReactor去负责接收到的connection if (++next == selectors.length) next = 0; } } mainReactor负责监听连接,accept连接给subReactor处理,为什么要单独分一个Reactor来处理监听呢?因为像TCP这样需要经过3次握手才能建立连接,这个建立连接的过程也是要耗时间和资源的,单独分一个Reactor来处理,可以提高性能。 参考: http://www.cnblogs.com/fxjwind/p/3363329.html 本文转自阿凡卢博客园博客,原文链接:http://www.cnblogs.com/luxiaoxun/p/4331110.html,如需转载请自行联系原作者
系列回顾 本系列前面有三篇文章介绍和演示了AgileEAS.NET平台ORM组件的开发流程及其常见的使用方式,通过前面的三篇文章,大家都可以正常的使用ORM进行正常的开发,本文将提到一个ORM结构性的问题,ORM对象的访问器。 情况说明 提到ORM访问器,我们就不得不提到一个面对对象设计的问题,那就是到底是对象.操作(),还是操作者.操作(对象),对于这样一个有着争论性并且也没有一个明确最优结果的问题,我也不敢在本文中详细的介绍,我将会在合适的时机发布一个讨论:面向对象设计中的对象.操作()还是操作者.操作(对象)。 访问模式变化 AgileEAS.NET平台中的ORM最早是基于对象.操作()的这种思路设计的,在最初的版本中ORM实体对象(IEntity)和表对象(ITable)中包含了ORM的基本操作:读取、更新、删除、插件操作: 我们可以IEntity的定义可以看到,实体记录接口定义了Query、Refresh、Inert、Update、Delete等与数据库同步的操作,也定义了CacheRefresh这样的缓存刷新操作,同样ITable对象也定义了他的操作: ITable接口定义了Query、Update、Delete等与数据库同步的操作,也定义了CacheQuery这样的缓存查询操作。 在最初的ORM实现中,由ITable和IEntity的实现Table和Entity两个基类中直接实现这些方法,实质上在最高的ORM体系中就不存在ITable和IEntity接口,在那时还没有需要要求基于接口驱动。 至今为止,ORM实体对象(IEntity和ITable)还包含着这一组方法的定义,在漫长的应用开发中prodct.Insert()这样的写法非常的普遍。 在AgileEAS.NET平台ORM的变迁历史中,有两个事情改变了ORM对象及其访问器体系,第一件事是,同一应用要在不同数据库之上运行的需要驱动了基于接口驱动的数据层开发,也就是提出了ITable和IEntity接口,第二件事是SAAS/分布式应用环境催生了ORM访问器的诞生,进而实现了ORM组件定义与操作的分离。 下面我们来看一看ORM访问器的定义IOrmAccessor: 缓存访问器ICacheAccessor: 平台目录在EAS.Data.dll程序中集内置了一个基于数据库连接的ORM访问器(OrmAccessor),他必须基于一个事实存在的数据库连接IConnection和IAccessor访问器,也内置了一个基于内存ORM缓存访问器(CacheAccessor)。 同时,在AgileEAS.NET平台中实现了基于Remoting技术和WebService技术的分布式技术的分布式ORM访问器。 有了ORM访问器,我们在应用开发过程中,就可以使用操作者.操纵(对象)这样的模式进行ORM操作,例如ormAccessor.Insert(product)。 两种模式的集成 AgileEAS.NET平台中的ORM通过ORM访问器提供了操作者.操纵(对象)的这种处理模型,ORM在不同时期实现了这两种不同方法的处理,对于这两种方式,谁也无法说出那个具有决定的优点,一切都是相对的,在操作的方便性上,在面向对象的理论体系上。 AgileEAS.NET平台中的ORM把实体的定义与访问进行了剥离,然后又把ORM对象与访问器进行了一个集成和粘合,即达到如下的结果: 1.ORM即可以通过实体.操作()也可以通过访问器.操纵(实体)完成对ORM实体的操纵。 2.分离ORM实体对象的操作代码,保在ORM实体对象中保留与实体定义相关的代码,实体对象上定义OrmAccessor属性,实现上的操作方法调用Orm访问器的实体操作方法。 3.ORM实体对象与ORM访问器接口偶尔,基于接口驱动,通过代码或者配置,在运行时使用不同的访问器实现。 在实际使用中我发两段等效代码: /// <summary> /// 输出全表数据 /// </summary> public void DemoQuery() { ProductList table = new ProductList(); OrmContext.OrmAccessor.Query(table); int cols = table.Columns.Count; foreach (Product product in table.Rows) { //do } } 等同于: /// <summary> /// 输出全表数据 /// </summary> public void DemoQuery() { ProductList table = new ProductList(); table.OrmAccessor = OrmContext.OrmAccessor; table.Query(); int cols = table.Columns.Count; foreach (Product product in table.Rows) { //do } } 访问器配置 之前ORM演示的例子我对ORM访问器使用报一个OrmContext进行了声明,在OrmContext类中,对Orm访问器使用直接new的方式进行了实例化: /// <summary> /// Orm访问器。 /// </summary> public static IOrmAccessor OrmAccessor { get { if (Instance.ormAccessor == null) { Instance.ormAccessor = new OrmAccessor(); Instance.ormAccessor.DataAccessor = DataAccessor; } return Instance.ormAccessor; } } 从代码中我们看到Instance.ormAccessor = new OrmAccessor(),这样一来应用业务与访问器的实现进行了耦合,Instance.ormAccessor.DataAccessor = DataAccessor; 这一句完成ORM访问器所依赖的数据访问器的注入,程序并没有有效的解耦。 解决这个问题的办法,还是老方法,使用AgileEAS.NET平台的控制反转(IOC)组件来完成访问器的解耦,有关AgileEAS.NET平台IOC组件的介绍请参见AgileEAS.NET平台之对象控制反转一文。 首先我们用以下代码替换OrmContext类: OrmContext 1 static class OrmContext 2 { 3 /// <summary> 4 /// Orm访问器。 5 /// </summary> 6 public static IOrmAccessor OrmAccessor 7 { 8 get 9 {10 return ContextHelper.GetContext().Container.GetComponentInstance("OrmAccessor") as IOrmAccessor;11 }12 }13 } 向ClassLib.OrmDemo项目添加一个应用程序配置文件app.config,并写如以下信息: 1 <?xml version="1.0" encoding="utf-8"?> 2 <configuration> 3 <configSections> 4 <section name="EAS.Objects" type="EAS.Objects.ConfigHandler,EAS.IOCContainer"/> 5 </configSections> 6 <EAS.Objects> 7 <object name="DataConnection" assembly="EAS.Data" type="EAS.Data.Access.SqlClientConnection" LifestyleType="Singleton"> 8 <property name="ConnectionString" type="string" value="Data Source=vm2003;Initial Catalog=eas;User ID=sa" /> 9 </object>10 <object name="OrmAccessor" assembly="EAS.Data" type="EAS.Data.ORM.OrmAccessor" LifestyleType="Singleton">11 <property name="DbConnection" type="object" value="DataConnection" />12 </object>13 <!--<object name="CacheAccessor" assembly="EAS.Data" type="EAS.Data.ORM.CacheAccessor" LifestyleType="Singleton">14 </object>-->15 <object name="DataAccessor" assembly="EAS.Data" type="EAS.Data.Access.SqlClientAccessor" LifestyleType="Singleton">16 <property name="Connection" type="object" value="DataConnection" />17 </object>18 </EAS.Objects>19 </configuration> 重新编译运行,结束本次演示,在一步篇文章中我将介绍ORM中使用SQL语句实现ORM不能实现的特定业务。 有关本例子所涉及的数据表结构请参考基于AgileEAS.NET平台基础类库进行应用开发-总体说明及数据定义一文,有关数据对象模型定义文件、文档、DDL脚本请下载:http://files.cnblogs.com/eastjade/demo.db.doc.sql.rar,本文代码下载:ORM.Demo4.rar。 链接 一步一步教你使用AgileEAS.NET基础类库进行应用开发-系列目录 AgileEAS.NET平台开发指南-系列目录 AgileEAS.NET应用开发平台介绍-文章索引 AgileEAS.NET平台应用开发教程-案例计划 AgileEAS.NET官方网站 敏捷软件工程实验室 QQ群:116773358 作者:魏琼东 出处:http://www.cnblogs.com/eastjade关于作者:有13年的软件从业经历,专注于中小软件企业软件开发过程研究,通过在技术与管理帮助中小软件企业实现技术层面开源节流的目的。熟悉需求分析、企业架构、项目管理。现主要从事基于AgileEAS.NET平台的技术咨询工作,主要服务于医疗卫生、铁路、电信、物流、物联网、制造、零售等行业。如有问题或建议,请多多赐教! 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过mail.james@qq.com 联系我,也可以加入QQ群:113723486、199463175、116773358、116773358、212867943、147168308、59827496、193486983、15118502和大家共同讨论,非常感谢。 本文转自魏琼东博客园博客,原文链接:http://www.cnblogs.com/eastjade/archive/2010/10/03/1841534.html,如需转载请自行联系原作者
在实际的工作中,有时我们需要对一些网页进行截图,一般的网页截图的代码如下(VB2010) 这段代码用到了辅助类clsCaptureSettings。这个类有3个字段:Url:要访问的网页的地址;Width:要截图的宽度,默认是1024;TimeOut:超时设置,默认是180秒; 以上代码实现截图的关键就是两句话 _Web.Height = _Web.Document.Body.ScrollRectangle.Height 把WebBrowser的高度设置和网页高度一致 _Web.DrawToBitmap(_Bmp, R) 将WebBrowser类中的内容画到位图对象 上面的代码经测试,会有如下的两个问题 1、当WebBrowser的高度设置超过20000(是个约数,没有仔细测量过)时,DrawToBitmap方法会有一定几率失效,没法完成截图。而且,WebBrowser的高度越大,失效的几率越大。 2、WebBrowser的高度也不是能无限设置的,其上限是65536,超过这个上限的时候,Webbrowser类会自动设置高度为65536,而当高度设置为65536时,DrawToBitmap方法失效的几率几乎是100% 这样,上面的代码在截取超长网页的时候就会出现问题,几乎不能完成网页的截图。 于是,需要改动代码。利用滚屏实现网页截图。 实现滚屏的技术难点在于,一是如何通过代码滚动网页?通过查阅资料,用如下的代码即可。 _Web.Document.Window.Parent.ScrollTo(X, Y) 该代码将网页滚动到水平X,垂直Y的位置。 二是,如何获得当前网页滚动的垂直位置?代码如下: _Web.Document.Body.Parent.ScrollTop 因此,改进后的代码如下: Private Shared Function CaptureWeb(Settings As Object)As Object Dim _Settings As clsCaptureSettings = CType(Settings, clsCaptureSettings) Dim _Bmp As Bitmap =Nothing Dim iAs Integer Const WEB_HEIGHT As Integer = 10000 Using _Web As NewWebBrowser _Web.ScrollBarsEnabled =False _Web.Width = _Settings.Width _Web.Height = WEB_HEIGHT Dim _Time As Date = Now.AddSeconds(_Settings.TimeOut) _Web.Navigate(_Settings.Url) Do Until (_Web.ReadyState = WebBrowserReadyState.Complete) OrElse (Now > _Time) Application.DoEvents() Loop _Web.Stop() Dim _WebHeightAs Integer If _Web.Document.BodyIs Nothing Then _WebHeight = 500 Else _WebHeight = _Web.Document.Body.ScrollRectangle.Height End If _Bmp = New Bitmap(_Web.Width, _WebHeight) Dim R As Rectangle = New Rectangle(0, 0, _Web.Width, WEB_HEIGHT) For i = 0 To _WebHeight - 1 Step WEB_HEIGHT _Web.Document.Window.Parent.ScrollTo(0, i) If _Web.Document.Body.Parent.ScrollTop = i Then _Web.DrawToBitmap(_Bmp, R) R.Offset(0, WEB_HEIGHT) Else R.Y = _Web.Document.Body.Parent.ScrollTop _Web.DrawToBitmap(_Bmp, R) End If Next End Using Return _Bmp End Function 此改进后的代码相较之前的代码增加了滚动网页的代码,因此在截相同的网页的时候,效率会差点,但是可能截一些超长网页。 什么地方会出线超长网页?很多大家不注意的地方,那就是论坛,一般论坛都是主题一个,每页的回复数是30个。这样,很容易整个网页的长度就超过65536了。用之前的代码是无法实现截图的,而用改进后的代码就可以实现这点。 本文转自万仓一黍博客园博客,原文链接:http://www.cnblogs.com/grenet/archive/2012/08/03/2621482.html,如需转载请自行联系原作者