posts - 50, comments - 5, trackbacks - 0, articles - 1
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

2007年9月30日

    在第一部分,我们介绍服务器端的开发平台,Java 2,J2ee 。j2ee是原则的集合,编码的标准和革命。通过j2ee,通过j2ee,你可以迅速的构建分布,可靠的,轻便安全的服务器端发布。

第一章:分析服务器端组件结构,例如EJB的需求。你将看到丰富的需求,如高端的,高可用用的,资源管理和安全等方面。我们将讨论如何将EJB结构融入到SOA的示例。同时,我们也将用一定的篇幅来讲一下j2ee服务器端的发布平台。

第二章:将介绍Enterprise JavaBean的基础知识,我们将了解一下request interception的原则,这对于了解EJB的工作方法是比较重要的。我们同时会了解一下不同的文件,关于他们如何与Bean一起工作。

第三章:在这里,我们将完成我们第一个简单的bean。我们将详细的介绍每一个组成bean的文件代码,和在客户端如何调用Bean。

posted @ 2007-09-30 14:14 daniel-shen 阅读(113) 评论(0) 编辑

2007年4月23日

主板
   之所以把这东西放在第一位,是因为作为它太重要。 我们常见的主板是ATX主板。它是采用印刷电路板(PCB)制造而成。是在一种绝缘材料上采用电子印刷工艺制造的。市场上主要有4层板与6层板二种。常见 的都是4层板。用6层PCB板设计的主板不易变形,稳定性大大提高。如果你有幸买到了6层板,那可绝对超值啊!哈!在主板的每层都布满了电路,所以,如果 PCB板烧坏,比较轻的凭借我们工程师高超的技术,可以通过搭明线维修,比较严重的话,这片主板的生命也就到此结束了! 主板上面的零件看起来眼花缭乱,可他们都是非常有条有理的排列着。主要包括一个CPU插座;北桥芯片、南桥芯片、BIOS芯片等三大芯片;前端系统总线 FSB、内存总线、图形总线AGP、数据交换总线HUB、外设总线PCI等五大总线;软驱接口FDD、通用串行设备接口USB、集成驱动电子设备接口 IDE等七大接口。 一、主板上的主要芯片 1、 北桥芯片 MCH 在CPU插座的左方是一个内存控制芯片,也叫北桥芯片、一般上面有一铝质的散热片。北桥芯片的主要功能是数据传输与信号控制。它一方面 通过前端总线与CPU交换信号,另一方面又要与内存、AGP、南桥交换信号。北桥芯片坏了以后的现象多为不亮,有时亮后也不断死机。如果工程师判定你的北 桥芯片坏了,再如果你的主板又比较老的话,基本上就没有什么维修的价值了 2、 南桥芯片 ICH4 南桥芯片主要负责外部设备的数据处理与传输。比ICH4早的有ICH1、ICH2、ICH3,但它不支持USB2.0 。而ICH4 支持USB2.0 。区分它们也很简单:南桥芯片上有82801AB 82801BB 82801CB 82801DB 分别对应ICH1 ICH2  ICH3 ICH4 。南桥芯片坏后的现象也多为不亮,某些外围设备不能用,比如IDE口、FDD口等不能用,也可能是南桥坏了。因为南北桥芯片比较贵, 焊接又比较特殊,取下它们需要专门的BGA仪,所以一般的维修点无法修复南北桥。 3、 BIOS芯片 FWH 它是把一些直接的硬件信息固化在一个只读存储器内。是软件和硬件之间这重要接口。系统启动时首先从它这里调用一些硬件信息,它的性 能直接影响着系统软件与硬件的兼容性。例如一些早期的主板不支持大于二十G的硬盘等问题,都可以通过升级BIOS来解决。我们日常便用时遇到的一些与新设 备不兼容的问题也可以通过升级来解决。如果你的主板突然不亮了,而CPU风扇仍在转动,那么你首先应该考虑BIOS芯片是否损坏。 4、 系统时钟发生器 CLK 在主板的中间位置有个晶振元件,它会产生一系列高频脉冲波,这些原始的脉冲波再输入到时钟发生器芯片内,经过整形与分频,然后分 配给计算机需要的各种频率。 5、 超级输入输出接口芯片 I/O 它一般位于主板的左下方或左上方,主要芯片有Winbond 与ITE,它负责把键盘、鼠标、串口进来的串行数据转化为并行数据。同时也对并口与软驱口的数据进行处理。在我们的维修现场,诸如键盘与鼠标口坏,打印口 坏等一些外设不能用,多为I/O芯片坏,有时甚至造成不亮的现象。 6、 声卡芯片 因为现在的主板多数都集成了声卡,而且集成的多为AC’97声卡芯片。当然,也有CMI的8738声卡芯片等。如果你的集成声卡没有声音,这儿 坏了的可能性最大。 二、主板上主要的插座
  1、CPU插座  目前所有的主板都采用了socket系列零拔力插座。早期的P3采用的 socket370插座,现在的P4多采用socket478 插座,早期的P4也有采用socket423插座的,intel 的服务器CPU 如:至强(Xeon)则采用了socket603插座。Intel 对CPU封装格式的不断变化让我们这些fan 们给他送了不少钱啊!不过近日听说intel下一代CPU的封装格式还是采用socket478的格式,这对于不断追求性能的DIYer们来说可是一个好 消息啊。
  2、内存总线插座 现在市场上我们能见到的内存有SDRAM、DDR SDRAM、RAMBUS三种。SDRAM内存由于DDR 内存的价格下调已经逐渐淡出市场,它采用168线插座,中间与左边有两个防反插断口;DDR SDRAM由于非常高的性价比已经成为市场的主流。它采用 184线插座,在中间只有一个防反插断口;RAMBUS内存虽然性能好,但是价格一直高踞不下,加上intel已经放弃了对它的支持,所以它的前途至今还 只是一个悬念!它的插座采用184线RIMM插座,是在中间有两个防反插断口。 有些客户多次反映在845主板上有时内存认不全的现象,这是因为Iintel 845系列主板只能支持4个Bank (一个Bank可以理解为内存条的一面),在845系列主板上一般设有三个内存插槽,而第二个插槽与第三个插槽共享二个Bank。所以,如果你在第二个与 第三个插槽插的内存条为双面的256M,那么就只能认到一个256M。 3、AGP图形总线插座 它位于CPU插座的左边,呈棕色。它的频率为64MHZ。从速度上分为AGP2X,现在的多为AGP4X,也有一些主板已经支持 AGP8X。由于不同的速度所需要的电压不同,所以一些主板不亮主要是用户把老的AGP2X显卡插在的新的AGP2X主板上,从而把AGP插座烧坏!令人 欣慰的是一些新的主板已经在主板上集成了电压自动调节装置,它可以自动识别显卡的电压。
  4、PCI总线插座  它呈现为白色,在AGP插 座的旁边,因主板不同,多少不等。它的频率为32MHZ。多插网卡,声卡等其它一些外设。 5、IDE设备接口 它一般位于主板的下面。有四十针八十线。两个IDE口并在一起,有时一个呈绿色,表示它为IDE1。因为系统首先检测IDE1,所以 IDE1应该接系统引导硬盘。现在的主板多已支持ATA100,有得支持ATA133,但更高端的主板已经支持串行ATA,它是在并行传输速率无法进一步 提高的情况下出现的一种新的、具有更高传输速度的技术,也将是下一代的主流技术。 一口气说了这么多,我已经口干舌燥了,大家再看看自己的主板,是不是感觉它比以前熟悉了多了?哈哈!我们也到说再见的时候了,即然今天说主板,那么我就再 说一个关于主板的消息吧,我们技服中心近日接受了一批维修的板子,我们的工程师维修起来特别困难,后来经知情人士指点,才发现这批主板的PCB板边缘都有 一个针眼大小的缺口。不仔细看根本分辨不出来。大家可不要小看这个小口中,它是联想对报废主板打的专门的印记!我们居然修复了好多片,我都不得不偑服我们 的技术水平了!这可不是自夸的哟!所以,大家买二手主板时可一定要小心啊!
  CPU
  主要谈谈频率。 1.凡是懂得点电脑的朋友,都应该对'频率'两个字熟悉透了吧!作为机器的核心CPU的频率当然是非常重要的,因为它能直接影响机器的性能。那么,您是否 对CPU频率方面的问题了解得很透彻呢? 所谓主频,也就是CPU正常工作时的时钟频率,从理论上讲CPU的主频越高,它的速度也就越快,因为频率越高,单位时钟周期内完成的指令就越多,从而速度 也就越快了。但是由于各种CPU内部结构的差异(如缓存、指令集),并不是时钟频率相同速度就相同,比如PIII和赛扬,雷鸟和DURON,赛扬和 DURON,PIII与雷鸟,在相同主频下性能都不同程度的存在着差异。目前主流CPU的主频都在600MHz以上,而频率最高(注意,并非最快)的P4 已经达到1.7GHz,AMD的雷鸟也已经达到了1.3GHz,而且还会不断提升。
  在486出现以后,由于CPU工作频率不断提高,而 PC机的一些其他设备(如插卡、硬盘等)却受到工艺的限制,不能承受更高的频率,因此限制了CPU频率的进一步提高。因此,出现了倍频技术,该技术能够使 CPU内部工作频率变为外部频率的倍数,从而通过提升倍频而达到提升主频的目的。因此在486以后我们接触到两个新的概念--外频与倍频。它们与主频之间 的关系是外频X倍频=主频。一颗CPU的外频与今天我们常说的FSB(Front side bus,前端总线)频率是相同的(注意,是频率相同),目前市场上的CPU的外频主要有66MHz(赛扬系列)、100MHz(部分PIII和部分雷鸟以 及所有P4和DURON)、133MHz(部分PIII和部分雷鸟)。值得一提的是,目前有些媒体宣传一些CPU的外频达到了200MHz (DURON)、266MHz(雷鸟)甚至400MHz(P4),实际上是把外频与前端总线混为一谈了,其实它们的外频仍然是100MHz和 133MHz,但是由于采用了特殊的技术,使前端总线能够在一个时钟周期内完成2次甚至4次传输,因此相当于将前端总线频率提升了好几倍。不过从外频与倍 频的定义来看,它们的外频并未因此而发生改变,希望大家注意这一点。今天外频并未比当初提升多少,但是倍频技术今天已经发展到一个很高的阶段。以往的倍频 都只能达到2-3倍,而现在的P4、雷鸟都已经达到了10倍以上,真不知道以后还会不会更高。眼下的CPU倍频一般都已经在出厂前被锁定(除了部分工程样 品),而外频则未上锁。部分CPU如AMD的DURON和雷鸟能够通过特殊手段对其倍频进行解锁,而INTEL产CPU则不行。
  由于外频 不断提高,渐渐地提高到其他设备无法承受了,因此出现了分频技术(其实这是主板北桥芯片的功能)。分频技术就是通过主板的北桥芯片将CPU外频降低,然后 再提供给各插卡、硬盘等设备。早期的66MHz外频时代是PCI设备2分频,AGP设备不分频;后来的100MHz外频时代则是PCI设备3分频,AGP 设备2/3分频(有些100MHz的北桥芯片也支持PCI设备4分频);目前的北桥芯片一般都支持133MHz外频,即PCI设备4分频、AGP设备2分 频。总之,在标准外频(66MHz、100MHz、133MHz)下北桥芯片必须使PCI设备工作在33MHz,AGP设备工作在66MHz,才能说该芯 片能正式支持该种外频。
  最后再来谈谈CPU的超频。CPU超频其实就是通过提高外频或者倍频的手段来提高CPU主频从而提升整个系统的性 能。超频的历史已经很久远(其实也就几年),但是真正为大家所喜爱则是从赛扬系列的出产而开始的,其中赛扬300A超450、366超550直到今天还为 人们所津津乐道。而它们就是通过将赛扬CPU的66MHz外频提升到100MHz从而提升了CPU的主频。而早期的DURON超频则与赛扬不同,它是通过 破解倍频锁然后提升倍频的方式来提高频率。总的看来,超倍频比超外频更稳定,因为超倍频没有改变外频,也就不会影响到其他设备的正常运作;但是如果超外 频,就可能遇到非标准外频如75MHz、83MHz、112MHz等,这些情况下由于分频技术的限制,致使其他设备都不能工作在正常的频率下,从而可能造 成系统的不稳定,甚至出现硬盘数据丢失、严重的可能损坏。因此,笔者在这里告诫大家:超频虽有好处,但是也十分危险,所以请大家慎重超频!
  2.关于超频 如果是AMD的CPU要超的话就了解一下他的频率极限吧
   AMD在不久前发布了它们全新的Athlon XP处理器,其频率分别显XP1500+,1600+,1700+和1800+。为了对抗Intel Pentium4处理器,Athlon XP重新采用了PR值(性能指数)来标称处理器,而Ahlon XP1600+意味着拥有与Pentium 4 1600MHz相同的性能。
  Athlon XP采用了全新基于0.18微米制程的Palonmino核心,其核心面积由雷鸟的120mm2增加为128mm2。而封装方式也变为类似FC-PGA PentiumIII的OPGA封装。AMD宣称在采用新核心后 Athlon XP的发热量将较同频的雷鸟低20%。而更低的散热量,自然也就意味着更强劲的超频性能。
  所以,我们决定测试一下Athlon XP的超频能力。我们选择了性价比较好的Athlon XP 1600+。它比1800+要便宜许多,但超频能力似乎可以达到1900Mhz以上。
   Athlon XP同样有与雷鸟类似的L1桥路,不过已被激光切断,要想超频,首先必须将L1桥路重新相连。具体连接桥路的方式可以参见本站相关文章。由于处理器默认电 压为1.75v,要更好的发挥处理器的超频极限,这需要一块具备电压调节功能的主板。我们采用了磐英8K7A和8KHA+进行了对比,尽管8K7A在调节 方式上较不便,但超频性能却好于新的8KHA+。
  在解频之后,我们首先将倍频设置为6,然后将外频设置为最高,在8K7A下,我们将处理器超至最高200MHz(400MHz DDR)外频,通过200MHz外频下的内存性能测试,我们可以看出超频后的内存带宽已经超出AMD760芯片40%左右。
  刚才的测试仅仅只是风冷状态下的结果,这不过是个开始,接下来我们将在极限致冷环境下测试处理器的超频极限。安装上水冷器后。我们将电压调至2.1v。而VDDR调至2.9v。
  测试结果令人惊叹,我们最终将处理器稳定于178MHz外频下,此时频率已高达1873.89MHz。
  虽然我们希望能突破1900MHz的障碍,但没有成功。同时我们也发现主板对于Athlon XP的超频也致关重要,虽然8KHA+采用更新的芯片组并拥有更好的性能,但在超频能力方面却不如其前辈8K7A。而新核心的Athlon XP超频能力,也得到了验证。
  内存
  1.内存的基础知识 RAM技术词汇
   CDRAM-Cached DRAM--高速缓存存储器 CVRAM-Cached VRAM--高速缓存视频存储器 DRAM-Dynamic RAM--动态存储器 EDRAM-Enhanced DRAM--增强型动态存储器 EDO RAM-Extended Date Out RAM--外扩充数据模式存储器 EDO SRAM-Extended Date Out SRAM--外扩充数据模式静态存储器 EDO VRAM-Extended Date Out VRAM--外扩充数据模式视频存储器 FPM-Fast Page Mode--快速页模式 FRAM-Ferroelectric RAM--铁电体存储器 SDRAM-Synchronous DRAM--同步动态存储器 SRAM-Static RAM--静态存储器 SVRAM-Synchronous VRAM--同步视频存储器 3D RAM-3 DIMESION RAM--3维视频处理器专用存储器 VRAM-Video RAM--视频存储器 WRAM-Windows RAM--视频存储器(图形处理能力优于VRAM) MDRAM-MultiBank DRAM--多槽动态存储器 SGRAM-Signal RAM--单口存储器
  存储器有哪些主要技术指标
  存储器是具有“记忆”功能的设备,它用具有两种稳定状态的物理器件来表示二 进制数码 “0”和“1”,这种器件称为记忆元件或记忆单元。记忆元件可以是磁芯,半导体触发器、 MOS电路或电容器等。 位(bit)是二进制数的最基本单位,也是存储器存储信息的最小单位,8位二进制数称为一 个字节(Byte),可以由一个字节或若干个字节组成一个字(Word)在PC机中一般认为1个或2个字节组成一个字。若干个忆记单元组成一个存储单元, 大量的存储单元的集合组成一个 存储体(MemoryBank)。为了区分存储体内的存储单元,必须将它们逐一进行编号,称为地址。地址与存储单元之间一一对应,且是存储单元的唯一标 志。应注意存储单元的地址和它里面存放的内容完全是两 回事。 根据存储器在计算机中处于不同的位置,可分为主存储器和辅助存储器。在主机内部,直接 与CPU交换信息的存储器称主存储器或内存储器。在执行期间,程序的数据放在主存储器内。各个存储单元的内容可通过指令随机读写访问的存储器称为随机存取 存储器(RAM)。另一种存储器叫只读存储器(ROM),里面存放一次性写入的程序或数据,仅能随机读出。RAM和ROM共同分享主存储器的地址空间。 RAM中存取的数据掉电后就会丢失,而掉电后ROM中 的数据可保持不变。因为结构、价格原因,主存储器的容量受限。为满足计算的需要而采用了大容量的辅助存储 器或称外存储器,如磁盘、光盘等.存储器的特性由它的技术参数来描述。
  存储容量:存储器可以容纳的二进制信息量称为存储容量。一般主存储 器(内存)容量在几十K到几十M字节左右;辅助存储器(外存)在几百K到几千M字节。 存取周期:存储器的两个基本操作为读出与写入,是指将信息在存储单元与存储寄存器(MDR)之间进行读写。存储器从接收读出命令到被读出信息稳定在MDR 的输出端为止的时间间隔,称为取数时间TA;两次独立的存取操作之间所需的最短时间称为存储周期TMC。半导 体存储器的存取周期一般为60ns-100ns。 存储器的可*性:存储器的可*性用平均故障间隔时间MTBF来衡量。MTBF可以理解为两次故障之间的平均时间间隔。MTBF越长,表示可*性越高,即保 持正确工作能力越强。 性能价格比:性能主要包括存储器容量、存储周期和可*性三项内容。性能价格比是一个综合性指标,对于不同的存储器有不同的要求。对于外存储器,要求容量极 大,而对缓冲存储器则要求速度非常快,容量不一定大。因此性能/价格比是评价整个存储器系统很重要的 指标。
  SDARM能成为下一代内存 的主流吗 快页模式(FPM)DRAM的黄金时代已经过去。随着高效内存集成电路的出现和为优化Pentium 芯片运行效能而设计的INTEL HX、VX等核心逻辑芯片组的支持,人们越来越倾向于采用扩 展数据输出(EDO)DRAM。 EDO DRAM采用一种特殊的内存读出电路控制逻辑,在读写一个地址单元时,同时启动下一个连续地址单元的读写周期。从而节省了重选地址的时间,使存储总线的速 率提高到40MHz。也就是说,与快页内存相比,内存性能提高了将近15%~30%,而其制造成本与快页 内存相近。但是EDO内存也只能辉煌一时,其称霸市场的时间将极为短暂。不久以后市场上主流CPU的主频将高达200MHz以上。为优化处理器运行效能, 总线时钟频率至少要达到66MHz以上。 多媒体应用程序以及Windows 95和WindowsNT操作系统对内存的要求也越来越高,为缓解 瓶颈,只有采用新的内存结构,以支持高速总线时钟频率,而不至于插入指令等待周期。这样,为适应下一代主流CPU的需要,在理论上速度可与CPU频率同 步,与CPU共享一个时钟 周期的同步DRAM(SYNCHRONOUS DRAMS)即SDRAM(注意和用作CACHE的SRAM区别,SRAM的全 写是Static RAM即静态RAM,速度虽快,但成本高,不适合做主存)应运而生,与其它内存 结构相比,性能\价格比最高,势必将成为内存发展的主流。 SDRAM基于双存储体结构,内含两个交错的存储阵列,当CPU从一个存储体或阵列访问数据的同时,另一个已准备好读写数据。通过两个存储阵列的紧密切 换,读取效率得到成倍提高。去年推出的SDRAM最高速度可达100MHz,与中档Pentium同步,存储时间高达5~8ns,可将Pentium系统 性能提高140%,与Pentium 100、133、166等每一档次只能提高性能百分之几十的CPU相比,换用SDRAM似乎是更明智的升级策略。 在去年初许多DRAM生产厂家已开始上市4MB×4和2MB×8的16MB SDRAM内存条,但其成本 较高。现在每一个内存生产厂家都在扩建SDRAM生产线。预计到今年底和1998年初,随着 64M SDRAM内存条的大量上市,SDRAM将占据主导地位。其价格也将大幅下降。 但是SDRAM的发展仍有许多困难要加以克服,其中之一便是主板核心逻辑芯片组的限制。VX 芯片组已开始支持168线SDRAM,但一般VX主板只有一条168线内存槽,最多可上32M SDRAM,而简洁高效的HX主板则不支持SDRAM。预计下一代Pentium主板芯片组TX将更好的支持SDRAM。Intel最新推出的下一代 Pentium主板芯片组TX将更好的支持SDRAM。 SDRAM不仅可用作主存,在显示卡专用内存方面也有广泛应用。对显示卡来说,数据带宽越宽,同时处理的数据就越多,显示的信息就越多,显示质量也就越 高。以前用一种可同时进行读写的双端口视频内存(VRAM)来提高带宽,但这种内存成本高,应用受很大限制。因此在 一般显示卡上,廉价的DRAM和高效的EDO DRAM应用很广。但随着64位显示卡的上市,带 宽已扩大到EDO DRAM所能达到的带宽的极限,要达到更高的1600×1200的分辨率,而又尽量降低成本,就只能采用频率达66MHz、高带宽的SDRAM了。 SDRAM也将应用于共享内存结构(UMA)--一种集成主存和显示内存的结构。这种结构在很 大程度上降低了系统成本,因为许多高性能显示卡价格高昂,就是因为其专用显示内存成本极高,而UMA技术将利用主存作显示内存,不再需要增加专门显示内 存,因而降低了成本。
  什么是Flash Memory 存储器 介绍关于闪速存储器有关知识 近年来,发展很快的新型半导体存储器是闪速存储器(Flash Memory)。它的主要特点是在不加电的情况下能长期保持存储的信息。就其本质而言,Flash Memory属于EEPROM(电擦除可编程只读存储器)类型。它既有ROM的特点,又有很高的存取速度,而且易于擦除和重写, 功耗很小。目前其集成度已达4MB,同时价格也有所下降。 由于Flash Memory的独特优点,如在一些较新的主板上采用Flash ROM BIOS,会使得BIOS 升级非常方便。 Flash Memory可用作固态大容量存储器。目前普遍使用的大容量存储器仍为硬盘。硬盘虽有容量大和价格低的优点,但它是机电设备,有机械磨损,可*性及耐用性 相对较差,抗冲击、抗振动能力弱,功耗大。因此,一直希望找到取代硬盘的手段。由于Flash Memory集成度不断提高,价格降低,使其在便携机上取代小容量硬盘已成为可能。 目前研制的Flash Memory都符合PCMCIA标准,可以十分方便地用于各种便携式计算机中以取代磁盘。当前有两种类型的PCMCIA卡,一种称为Flash存储器卡, 此卡中只有Flash Memory芯片组成的存储体,在使用时还需要专门的软件进行管理。另一种称为Flash驱动卡,此卡中除Flash芯片外还有由微处理器和其它逻辑电路 组成的控制电路。它们与IDE标准兼容,可在DOS下象硬盘一样直接操作。因此也常把它们称为Flash固态盘。 Flash Memory不足之处仍然是容量还不够大,价格还不够便宜。因此主要用于要求可*性高,重量轻,但容量不大的便携式系统中。在586微机中已把BIOS系 统驻留在Flash存储 器中。
  什么是Shadow RAM 内存 Shadow RAM也称为“影子”内存。它是为了提高系统效率而采用的一种专门技术。 Shadow RAM所使用的物理芯片仍然是CMOS DRAM(动态随机存取存储器)芯片。Shadow RAM 占据了系统主存的一部分地址空间。其编址范围为C0000~FFFFF,即为1MB主存中的768KB~1024KB区域。这个区域通常也称为内存保留 区,用户程序不能直接访问。 Shadow RAM的功能是用来存放各种ROM BIOS的内容。或者说Shadow RAM中的内容是ROM BIOS的拷贝。因此也把它称为ROM Shadow(即Shadow RAM的内容是ROM BIOS的“影 子”)。 在机器上电时,将自动地把系统BIOS、显示BIOS及其它适配器的BIOS装载到Shadow RAM 的指定区域中。由于Shadow RAM的物理编址与对应的ROM相同,所以当需要访问BIOS时, 只需访问Shadow RAM即可,而不必再访问ROM。 通常访问ROM的时间在200ns左右,而访问DRAM的时间小于100ns(最新的DRAM芯片访问时间为60ns左右或者更小)。在系统运行的过程 中,读取BIOS中的数据或调用BIOS中的程序模块是相当频繁的。显然,采用了Shadow技术后,将大大提高系统的工作效率。 按下按键你可以看到该地址空间分配图,在如图所示的1MB主存地址空间中,640KB以下的区域是常规内存。640KB~768KB区域保留为显示缓冲 区。768KB~1024KB区域即为Shadow RAM区。在系统设置中,又把这个区域按16KB大小的尺寸分为块,由用户设定是否允许使 用。 C0000~C7FFF这两个16KB块(共32KB )通常用作显示卡的ROM BIOS的Shadow区。 C8000~EFFFF这10个16KB块可作为其它适配器的ROM BIOS的Shadow区。F0000~FFFFF 共64KB规定由系统ROM BIOS使用。 应该说明的是,只有当系统配置有640KB以上的内存时才有可能使用Shadow RAM。在系统内存大于640KB时,用户可在CMOS设置中按照ROM Shadow分块提示,把超过640KB以上的 内存分别设置为“允许”(Enabled)即可。
  什么是EDO RAM 内存是计算机中最主要的部件之一。微机诞生以来,它的心脏--CPU几经改朝换代,目前已 发展到了PentiumⅡ,较之于当初,它在速度上已有两个数量级的增长。而内存的构成器件RAM(随机存储器)--一般为DRAM(动态随机存储器), 虽然单个芯片的容量不断扩大,但存取速度并没有太大的提高。虽然人们早就采用高速但昂贵的SRAM芯片在CPU和内存之间增加一种缓冲设备-- Cache,以缓冲两者之间的速度不匹配问题。但这并不能根本解决问题。于 是人们把注意力集中到DRAM接口(芯片收发数据的途径上)。 在RAM芯片之中,除存储单元之外,还有一些附加逻辑电路,现在,人们已注意到RAM芯片 的附加逻辑电路,通过增加少量的额外逻辑电路,可以提高在单位时间内的数据流量,即所 谓的增加带宽。EDO正是在这个方面作出了尝试。 扩展数据输出(Extended data out--EDO,有时也称为超页模式--hyper-page-mode)DRAM,和突发式EDO(Bust EDO-BEDO)DRAM是两种基于页模式内存的内存技术。EDO大约一年前被 引入主流PC,从那以后成为许多系统厂商的主要内存选择。BEDO相对更新一些,对市场的 吸引还未能达到EDO的水平。 EDO的工作方式颇类似于FPM DRAM:先触发内存中的一行,然后触发所需的那一列。但是当 找到所需的那条信息时,EDO DRAM不是将该列变为非触发状态而且关闭输出缓冲区(这是FPM DRAM采取的方式),而是将输出数据缓冲区保持开放,直到下一列存取或下一读周期开始。由于缓冲区保持开放,因而EDO消除了等待状态,且突发式传送更 加迅速。 EDO还具有比FPM DRAM的6-3-3-3更快的理想化突发式读周期时钟安排:6-2-2-2。这使得在66MHz总线上从DRAM中读取一组由四个元素组成的数据块时能 节省3个时钟周期。EDO 易于实现,而且在价格上EDO与FPM没有什么差别,所以没有理由不选择EDO。 BEDO DRAM比EDO能更大程度地改善FPM的时钟周期。由于大多数PC应用程序以四周期突 发方式访问内存,以便填充高速缓冲内存 (系统内存将数据填充至L2高速缓存,如果没有 L2高速缓存,则填充至CPU),所以一旦知道了第一个地址,接下来的三个就可以很快地由 DRAM提供。BEDO最本质的改进是在芯片上增加了一个地址计数器,用来跟踪下一个地址。 BEDO还增加了流水线级,允许页访问周期被划分为两个部分。对于内存读操作,第一部分负责将数据从内存阵列中读至输出级(第二级锁存),第二部分负责从 这一锁存将数据总线驱动至相应的逻辑级别。因为数据已经在输出缓冲区内,所以访问时间得以缩短。BEDO能达到的最大突发式时钟安排为5-1-1-1(采 用52nsBEDO和66-MHz总线)比优化EDO内存又节省 了四个时钟周期。
  RAM是如何工作的 实际的存储器结构由许许多多的基本存储单元排列成矩阵形式,并加上地址选择及读写控制 等逻辑电路构成。当CPU要从存储器中读取数据时,就会选择存储器中某一地址,并将该地 址上存储单元所存储的内容读走。 早期的DRAM的存储速度很慢,但随着内存技术的飞速发展,随后发展了一种称为快速页面 模式(Fast Page Mode)的DRAM技术,称为FPDRAM。FPM内存的读周期从DRAM阵列中某一行的触发开始,然后移至内存地址所指位置的第一列并触发,该位置即 包含所需要的数据。第一条信息需要被证实是否有效,然后还需要将数据存至系统。一旦发现第一条正确信息,该列即被变为非触发状态,并为下一个周期作好准 备。这样就引入了“等待状态”,因为在该列为非触发状态时不会发生任何事情(CPU必须等待内存完成一个周期)。直到下一周期开始或下一条信息被请求时, 数据输出缓冲区才被关闭。在快页模式中,当预测到所需下一条数据所放位置相邻时,就触发数据所在行的下一列。下一列的触发只有在内存中给定行上进行 顺序读操作时才有良好的效果。 从50纳秒FPM内存中进行读操作,理想化的情形是一个以6-3-3-3形式安排的突发式周期(6个时钟周期用于读取第一个数据元素,接下来的每3个时钟 周期用于后面3个数据元素)。第一个阶段包含用于读取触发行列所需要的额外时钟周期。一旦行列被触发后,内存 就可以用每条数据3个时钟周期的速度传送数据了。 FP RAM虽然速度有所提高,但仍然跟不上新型高速的CPU。很快又出现了EDO RAM和SDRAM等新型高速的内存芯片。
  介绍处理器高速缓存的有关知识
  所谓高速缓存,通常指的是Level 2高速缓存,或外部高速缓存。L2高速缓存一直都属于 速度极快而价格也相当昂贵的一类内存,称为SRAM(静态RAM),用来存放那些被CPU频繁使 用的数据,以便使CPU不必依赖于速度较慢的DRAM。 最简单形式的SRAM采用的是异步设计,即CPU将地址发送给高速缓存,由缓存查找这个地 址,然后返回数据。每次访问的开始都需要额外消耗一个时钟周期用于查找特征位。这样,异步高速缓存在66MHz总线上所能达到的最快响应时间为3-2-2 -2,而通常只能达到4-2-2-2。同步高速缓存用来缓存传送来的地址,以便把按地址进行查找的过程分配到两个或更多个时钟周期上完成。SRAM在第一 个时钟周期内将被要求的地址存放到一个寄存器中。在第二个时钟周期内,SRAM把数据传送给CPU。由于地址已被保存在一个寄存器中,所以接下来同步 SRAM就可以在CPU读取前一次请求的数据同时接收下一个数据地址。这样,同步SRAM可以不必另花时间来接收和译码来自芯片集的附加地址,就“喷出” 连续的数据元素。优化 的响应时间在66MHz总线上可以减小为2-1-1-1。 另一种类型的同步SRAM称为流水线突发式(pipelined burst)。流水线实际上是增加了一个 用来缓存从内存地址读取的数据的输出级,以便能够快速地访问从内存中读取的连续数据,而省去查找内存阵列来获取下一数据元素过程中的延迟。流水线对于顺序 访问模式,如高速 缓存的行填充(linefill)最为高效。
  什么是ECC内存 ECC是Error Correction Coding或Error Cheching and Correcting的缩写,它代表具有自动纠错功能的内存。目前的ECC存储器一般只能纠正一位二进制数的错误。 Intel公司的82430HX芯片组可支持ECC内存,所以采用82430HX芯片的主板一般都可以安装使用ECC内存,由于ECC内存成本比较高,所 以它主要应用在要求系统运算可*性比较高 的商业计算机中。由于实际上存储器出错的情况不会经常发生,所以一般的家用计算机不必采用ECC内存,还有不少控制电路芯片不能支持ECC内存,所以有不 少主机是不宜安装ECC内存的,用户应注 意对ECC内存不要盲从。
  SDRAM能与EDO RAM混用吗 SDRAM是新一代的动态存储器,又称为同步动态存储器或同步DRAM。它可以与CPU总线使用 同一个时钟,而EDO和FPM存储器则与CPU总线是异步的。目前SDRAM存储器的读写周期一般为5-1-1-1。相比之下,EDO内存器一般为6-2 -2-2。也就是说,SDRAM的读写周期比EDO少4个,大约节省存储器读写时间28%,但实际上由于计算机内其它设备的制约,使用 SDRAM的计算机大约可提高性能5~10%。 虽然有不少主机支持SDRAM与EDO内存混合安装方式,但是最好不要混用。原因是多数SDRAM只能在3.3V下工作,而EDO内存则多数在5V下工 作。虽然主机板上对DIMM和SIMM分别供电,但它们的数据线总是要连在一起的,如果SIMM(72线内存)与DIMM(168线SDRAM)混用,尽 管开始系统可以正常工作,但可能在使用一段时间后,会造成SDRAM的数据输入端 被损坏。 当然,如果你的SDRAM是宽电压(3V~5V)工作的产品,就不会出现这种损坏情况。目前T1和SUMSUNG的某些SDRAM产品支持宽电压工作方 式,可以与EDO内存混用。
  高速缓存--Cache 介绍Cache的分级 随着CPU的速度的加快,它与动态存储器DRAM配合工作时往往需要插入等待状态,这样难以发挥出CPU的高速度,也难以提高整机的性能。如果采用静态存 储器,虽可以解决该问题,但SRAM价格高。在同样容量下,SARM的价格是DRAM的4倍。而且SRAM体积大,集成 度低。为解决这个问题,在386DX以上的主板中采用了高速缓冲存储器--Cache技术。其基本思想是用少量的SRAM作为CPU与DRAM存储系统之 间的缓冲区,即Cache系统。80486以及更高档微处理器的一个显著特点是处理器芯片内集成了SRAM作为Cache,由于这些Cache装在芯片 内,因此称为片内Cache。486芯片内Cache的容量通常为8K。高档芯片 如Pentium为16KB,PowerPC可达32KB。Pentium微处理器进一步改进片内Cache,采用数据和双通道Cache技术,相对而 言,片内Cache的容量不大,但是非常灵活、方便,极大地提高了微处理器的性能。片内Cache也称为一级Cache。由于486,586等高档处理器 的时钟频率很高,一旦出现一级Cache未命中的情况,性能将 明显恶化。在这种情况下采用的办法是在处理器芯片之外再加Cache,称为二级Cache。二级Cache实际上是CPU和主存之间的真正缓冲。由于系统 板上的响应时间远低于CPU的速度,如果没有二级Cache就不可能达到486,586等高档处理器的理想速度。二级Cache的容量通常应比一级 Cache大一个数量级以上。在系统设置中,常要求用户确定二级Cache是否安装及尺寸大小等。二级Cache的大小一般为128KB、256KB或 512KB。在486以上档次的微机中,普遍采用256KB或512KB同步Cache。所谓同步是指Cache和CPU采用了相同的时钟周期,以相同的 速度同步工作。相对于异步Cache,性能可提高30% 以上。
  什么是CACHE存储器 所谓Cache,即高速缓冲存储器,是位于CPU和主存储器DRAM(Dynamic RAM)之间的规模较 小的但速度很高的存储器,通常由SRAM组成。SRAM(Static RAM)是静态存储器的英文缩写。由于SRAM采用了与制作CPU相同的半导体工艺,因此与动态存储器DRAM比较,SRAM 的存取速度快,但体积较大,价格很高。由于动态RAM组成的主存储器的读写速度低于CPU 的速度,而CPU每执行一条指令都要访问一次或多次主存,所以CPU总是要处于等待状态,严重地降低了系统的效率。采用Cache之后,在Cache中保 存着主存储器内容的部分副本,CPU在读写数据时,首先访问Cache。由于Cache的速度与CPU相当,因此CPU就能在零等待状态下迅速地完成数据 的读写。只有Cache中不含有CPU所需的数据时,CPU才去访问主存。CPU在访问Cache时找到所需的数据称为命中,否则称为未命中。因此,访问 Cache的命中率则成了提高效率的关键。而提高命中率则取决于Cache存储器的映象方式和Cache内 容替换的算法等一系列因素。
  对内存扩容时应遵循哪些规则
   对内存扩充容量时,应遵循下面的一些规则: 1.对大多数PC机来说,不能在同一组Bank内(每组包括两到四个插座)将不同大小的SIMM条混合在一起。很多PC机都可安装不同容量的SIMM,但 装在PC机同一组中的所有SIMM必须具有相同的容量,例如,对一个四插槽组来说,PC机一般既可接受1MB的SIMM条,也可 接受4MB的SIMM条,可在该组的每个槽内安装1MB SIMM,则这一组共可容纳4MB内存。也 可在该组每个槽内安装4MB SIMM,则这一组共可容纳16MB内存。但是,不能为了得到10MB内存,在两个槽内插入1MB的SIMM条,而在另两个槽中插入4MB的SIMM条。
  2.对于很多PC机来说,若把不同速度的SIMM混合在一起,即使它们的容量相同也会带来麻烦。例如,计算机中已有运行速度为60纳秒 (ns)的4MB内存,而文档中说70ns的SIMM也能工作。如果在母板的空闲内存槽中再插入速度为70ns的SIMM条,机器会拒绝引导或在启动后不 久就陷于崩溃。对于某些机器来说,若把速度低的SIMM放至第一组,则可解决速度 混合问题。计算机会按最低速度存取,剩余部分不会再有用。
  3.对于大多数PC机来说,必须将一组的所有插槽都插满。或者将一组全部置空(当然第一组 不行)。在一组中不能只装一部分。
   4.PC机可接受的SIMM大小有一个上限(最大值可从PC机说明书中找到。若没有说明书,唯 一的方法就是从实践中找到最大值了)。何谓30线、72线、168线内存条 内存条;30线;72线;168线 介绍30线、72线、168线内存条的有关知识及相互之间的区别条形存储器是把一些存储器芯片焊在一小条印制电路板上做成的,即称之为内存条,所谓内存条 线数即引脚数,按引脚数不同可把内存条分为30线的内存条、72线的内存条(SIMM, 即Sigle inline Memory Modale)和168线的内存条(DIMM,即Double inline Memory Module)。内存条的引脚数必须与主板上内存槽的插脚数相匹配,内存条插槽也有30线、72 线和168线三种。30线内存条提供8位有效数据位。常见容量有256KB、1MB和4MB。72线的内存条体积稍大,提供32位的有效数据位。常见容量 有4MB、8MB、16MB和32MB。按下按键你可以看到72线内存条的外观形状。 168线的内存条体积较大,提供64位有效数据位。
   如何识别Cache存储器芯片标志 目前微机系统中,常用的静态RAM的容量有8K×8位(64Kbit)、32K×8(256Kbit)位以及64K×8(512Kbit)位三种芯片,存 取时间(周期)为15ns到30ns。以上参数在静态SRAM芯片上常标注为:XX64-25(XX65-25)、XX256-15(XX257- 15)、XX512-15等。以XX256-15为例,其中“256”表示容量(单位为Kbit),“15”表示存取时间(单位为 ns)。在表示SRAM存储器容量的数值中,“64”与“65”相同,都表示该芯片的容量为64Kbit,即8KB。同理,“256”与“257”的含义 也相同,即该芯片的容量为32KB。例如在华硕PVI686SP3主板上使用的SRAM芯片为W24257AK-15,即该芯片的容量为32K×8位,存 取速 度为15ns。
  如何用软件的方法检测Cache? 检测;高速缓存;Cache 介绍用软件检测Cache的方法 ,主板上Cache的大小和有无很难用一般方法判断,尤其是有的主板连BIOS都被不法经销商修改过以方便作假。486时代常用的拔插法现在也不灵了-- 奔腾主板上很多标称256K的Cache芯片都是直接SMT(表面安装)上去的,无法拔插。测试Cache的软件确实有一些,如 CCT等,但普通用户很难得到这些专业软件。
  2.分类认识内存
  内存作为微型计算机的重要部件之一,已从早期的普通内存,发展到目前的同步动态内存,还有越来越广泛地应用于多媒体领域的RDRAM与后来的SDRAM Ⅱ、DDR RAM。
  内存大致的分类情况如下:
  1.FPM(Fast Page Mode)
  FPM(快页模式)是较早的个人计算机普遍使用的内存,它每隔3个时钟脉冲周期传送一次数据。现在已很少见到使用这种内存的计算机系统了。
  2.EDO(Extended Data Out)
   EDO(扩展数据输出)内存取消了主板与内存两个存储周期之间的时间间隔,每隔2个时钟脉冲周期传输一次数据,大大地缩短了存取时间,使存取速度提高 30%,达到60ns。EDO内存主要用于72线的SIMM内存条,以及采用EDO内存芯片的PCI显示卡(参阅本书后面的内容)。
  注: EDO内存条是普通DRAM内存的改进型,它比普通内存提高速度约10%20%左右。当它在完成某一单元信息的读写之前,能提前读写下一单元的信息,这样 就提高了内存的读写速度。但只是在普通内存的基础上改进了它的读写方式,但它的读写速度却仍然不够快,只能达到50ns60ns之间。对于CPU的几ns 的速度来说,仍然存在着很大的差别。
  这种内存流行在486以及早期的奔腾计算机系统中,它有72线和168线之分,采用5V电压,带宽 32 bit,可用于Intel FX/VX芯片组主板上,所以某些使用奔腾100/133的计算机系统目前还在使用它。不过要注意的是,由于它采用5V电压,跟下面将要介绍的SDRAM 不同(SDRAM为3.3v),两者混合使用时就会很容易会被烧毁,因此在使用前最好了解一下该主板使用的是3.3v还是5V电压。
  3.S(Synchronous)DRAM
  SDRAM(同步动态随机存储器)是目前奔腾计算机系统普遍使用的内存形式。SDRAM将CPU与RAM通过一个相同的时钟锁在一起,使RAM和CPU能够共享一个时钟周期,以相同的速度同步工作,与 EDO内存相比速度能提高50%。
  注:SDRAM采用的是新型的64位数据读写形式,内存条的引脚为168线,采用双列直插式的DIMM内存条,读写速度最高达到了10ns,是目前最快的内存芯片,同时也是奔腾II和奔腾III计算机系统首选的内存条。
   随着SDRAM的问世,快页模式(FPM)DRAM被很彻底打入了冷宫。由于高效内存集成电路的出现和为优化的奔腾CPU运行效能而设计的INTEL HX、VX等核心逻辑芯片组的支持, EDO DRAM被广泛采用了,它采用了一种特殊的内存读出电路控制逻辑,在读写一个地址单元时,同时启动下一个连续地址单元的读写周期。从而节省了重选地址的时 间,使存储总线的速率提高到 40 MHz。也就是说,因此说与快页内存相比性能提高了将近15%~30%,而其制造成本却与之相近,但是也只是辉煌了一时,面市的时间将极为短暂,这是为什 么呢?因此不久之后市场上主流CPU的主频高达200 MHz以上。为优化CPU的运行效能,总线时钟频率至少要达到66 MHz以上,多媒体应用程序以及Windows 95/97/98和Windows NT操作系统对内存的要求也越来越高,为缓解速度不够的瓶颈只有采用新的内存结构,否则就不能支持高速总线时钟频率,而不必于插入指令等待周期,在理论上 内存的速度需要与CPU频率同步,即与CPU共享一个时钟周期的同步动态内存(Synchronous DRAMS),所以SDRAM应运而生,与其它内存结构相比,性能/价格比最高,最终取代了它们成为了内存发展一个时期内的主流。
   SDRAM基于双存储体结构,内含两个交错的存储阵列,当CPU从一个存储体或阵列访问数据时,另一个就已为读写数据做好了准备,通过这两个存储阵列的紧 密切换,读取效率就能得到成倍的提高。SDRAM的速度早就超过了100MHz,存储时间达到5~ 8ns毫不费力,现在128 MB的SDRAM内存条也是大量上市,SDRAM占据市场的主导地位已是不可否认的事实,其价格也在大幅下降。
  SDRAM不仅可用作主 存,在显示卡上的内存方面也有广泛应用。对前者来说,数据带宽越宽,同时处理的数据就越多,显示的信息就越多,显示品质也就越高。在此之前的计算机系统还 用过可同时读写的双端口视频内存(VRAM)来提高带宽,但这种内存成本高,应用受很大限制。因此在一般显示卡上,廉价的DRAM和高效的EDO DRAM仍然还在应用着。但随着64位显示卡的上市,带宽已扩大到EDO DRAM所能达到的带宽的极限,要达到更高的1600×1200的分辨率,而又尽量降低成本,就只能采用频率达66MHz、高带宽的SDRAM了。 SDRAM还应用了共享内存结构(UMA),这在很大程度上降低了系统成本,因为许多高性能显示卡价格高昂,就是因为其专用显示内存成本极高所致,而 UMA技术将利用主存作显示内存,不再需要增加专门显示内存,因而降低了成本。
  注:SDRAM与用作Cache的SRAM是两个不同的概念,SRAM的全称是Static RAM(静态RAM),速度虽快,但成本高,不适合做主存。
  4. DDR SDRAM(SDRAM II)
   DDR(Double Data Rage双数据率) 也就是 SDRAMSDRAM II,是SDRAM的更新换代产品,它允许在时钟脉冲的上升沿和下降沿传输数据,这样不需要提高时钟的频率就能加倍提高SDRAM的速度,并具有比 SDRAM多一倍的传输速率和内存带宽,如64bit内存接口200MHz DDR SDRAM比PC100 SDRAM的内存带宽高一倍,266 MHz DDR SDRAM的内存带宽更是达到了2.12 GB/s。DDR SDRAM比800MHz RDRAM的内存带宽还要高,采用2.5v工作电压,价格也便宜非常多。过去,DDR SDRAM只是应用在显示卡上,现在由于DDR SDRAM标准已定制好,所以正有许多主板芯片组支持使用它。不过,第一款支持DDR SDRAM的芯片组并不是Intel推出的。而是由Micron推出的,其名称为Samurai DDR芯片,其性能的优秀性无论是在商业,还是游戏运行方面都赶得上Intel i840芯片组。但后者提供双RDRAM通道,可高达3.2 GB/s的内存带宽,比Samurai DDR 266 MHz DDR SDRAM提供的2.12G/秒的内存带宽高出33%,整体性能也要好一些,这其是因为RDRAM的潜伏等待时间要比SDRAM长,所以PC133 SDRAM(参阅下面的内容)和DDR SDRAM使得RDRAM在低端和高端系统上的优势全无,而DDR SDRAM更是成为了市场的主流。如,现代电子出品的64MB DDR SDRAM在128 MB内存总线,4Mx16颗,工作频率为333MHz,提供了5.3 GB/s的数据带宽,市场前景不用说了,一定会是不错的。
  5.RDRAM(Rambus DRAM)
  RDRAM(存储器总线式动态随机存储器)是Rambus公司开发的具有系统带宽、芯片到芯片接口设计的新型DRAM,它能在很高的频率范围下通过一个简单的总线传输数据,同时使用低电压信号,在高速同步时钟脉冲的两边沿传输数据。
  6.Flash Memory
   Flash Memory(闪速存储器)是一种新型半导体存储器,主要特点是在不加电的情况下长期保持存储的信息。就其本质而言,Flash Memory属于EEPROM(电擦除可编程只读存储器)类型,既有ROM的特点,又有很高的存取速度,而且易于擦除和重写,功耗很小。目前其集成度已达 4MB,同时价格也有所下降。由于这一独特优点,Flash Memory在一些较新的主板上普遍采用着,以便使得BIOS 升级非常方便,但时也会CIH这样的计算机病毒以可乘之机,让许多计算机饱受磨难。
  Flash Memory可用作固态大容量存储器,但目前普遍使用的大容量存储器仍为硬盘。硬盘虽有容量大和价格低的优点,但它是机电设备,有机械磨损,可*性及耐用 性相对较差,抗冲击、抗振动能力也弱,功耗也大。而Flash Memory集成度高,价格也在逐渐降低,专家们对它的应用前景相当乐观。
  7.Shadow RAM
   Shadow RAM也称为“影子内存”,是为了提高计算机系统效率而采用的一种专门技术,所使用的物理芯片仍然是CMOS DRAM(动态随机存取存储器,参阅本书后面的内容)芯片。Shadow RAM 占据了系统主存的一部分地址空间。其编址范围为C0000~FFFFF,即为1MB主存中的 768KB~1024KB区域。这个区域通常也称为内存保留区,用户程序不能直接访问。 Shadow RAM的功能就是是用来存放各种ROM BIOS的内容。也就是复制的ROM BIOS内容,因而又它称为ROM Shadow,这与Shadow RAM的意思一样,指得是ROM BIOS的“影 子”。现在的计算机系统,只要一加电开机,BIOS信息就会被装载到Shadow RAM中的指定区域里。由于Shadow RAM的物理编址与对应的ROM相同,所以当需要访问BIOS时, 只需访问Shadow RAM而不必再访问ROM,这就能大大加快计算机系统的运算时间。通常访问ROM的时间在200ns左右,访问DRAM的时间小于100ns、60ns, 甚至更短。
  在计算机系统运行期间,读取BIOS中的数据或调用BIOS中的程序模块的操作将是相当频繁的,采用了Shadow RAM技术后,无疑大大提高了工作效率。
  8.ECC内存
   ECC(Error Correction Coding或Error Cheching and Correcting)是一种具有自动纠错功能的内存,Intel的82430HX芯片组就支持它,使用该芯片的主板都可以安装使用ECC内存,但由于 ECC内存成本比较高,所以主要应用在要求系统运算可*性比较高的商业计算机中。由于实际上存储器出错的情况不会经常发生,相关的主板产品还不多,一般的 家用与办公计算机也不必采用ECC内存。
  9. CDRAM(Cached DRAM)
  CDRAM(Cached DRAM)带高速缓存动态随机存储器)是日本三菱电气公司开发的专有技术,它通过在DRAM芯片上集成一定数量的高速SRAM作为高速缓冲存储器和同步控 制接口来提高存储器的性能。这种芯片使用单一的+3.3V电源,低压TTL输入输出电平。
  10.DRDRAM(Direct Rambus DRAM)
   DRDRAM (接口动态随机存储器)是Rambus在Intel支持下制定的新一代RDRAM标准,与传统DRAM的区别在于引脚定义会随命令而变,同一组引脚线可以 被定义成地址,也可以被定义成控制线。其引脚数仅为正常DRAM的三分之一。当需要扩展芯片容量时,只需要改变命令,不需要增加芯片引脚。这种芯片可以支 持400MHz外频,再利用上升沿和下降沿两次传输数据,可以使数据传输率达到800MHz。同时通过把单个内存芯片的数据输出通道从8位扩展成16位, 这样在100MHz时就可以使最大数据输出率达1.6 GB/s。
  11.SLDRAM(Synchnonous Link DRAM)
   SLDRAM(同步链接动态内存)是由IBM、惠普、苹果、NEC、富士通、东芝、三星和西门子等大公司联合制定的,一种原本最有希望成为标准高速 DRAM的存储器。这是一种在原DDR DRAM基础上发展起来的高速动态读写存储器,具有与DRDRAM相同的高数据传输率,但其工作频率要低一些,可用于通信、消费类电子产品、高档的个人计 算机和服务器中。不过,由于各种各样的原因,这种动态存储器难以形成气候。
  12.VCM(Virtual Channel Memory)
   VCM(虚拟通道存储器)由NEC公司开发,是一种新兴的缓冲式DRAM,可用于大容量的SDRAM。此技术集成了“通道缓冲”功能,由高速寄存器进行 配置和控制。在实现高速数据传输,让带宽增大的同时还维持着与传统SDRAM的高度兼容性,所以通常也把VCM内存称为VCM SDRAM。
  13. FCRAM(Fast Cycle RAM)
   FCRAM(快速循环动态存储器)是由富士通和东芝联合开发的内存技术,数据吞吐速度可超过DRAM/SDRAM的4倍,能应用于需要极高内存带宽的系 统中,如服务器、3D图形及多媒体处理等场合,其主要的特点是:行、列地址同时(并行)访问,而不像普通DRAM那样首先访问行数据,再访问列数据。此 外,在完成上一次操作之前,便开始下一次操作。不过这并用于主内存,而是用于诸如显示内存这样的其他存储器上
  显卡
  对于每一位 追求电脑性能的DIY来说,显卡无疑是最重要的一样配件。在这个显卡技术高速发展的阶段,虽然可选择的显卡芯片厂商减少了,但基于相同厂商的显卡型号却分 得很细,性能也各不相同。其中繁复处可能即便是专业人员也难以尽述。用户选择显卡的时候对一些专业数据接触也多了,简单点如芯片内核频率、显存频率,复杂 点如像素填充率、显存带宽等。各显卡品牌在各自的显卡描述中也有这方面提及,但对于有些方面可能会有故意忽略某些细节,只提供那些炫目的优势数据,用户没 有完整的了解,这是缺乏公平性的。这里我主要给大家介绍一下显卡的性能参数,如何根据这些参数确定显卡的性能,希望你在下次选购显卡时能更好的选到自已所 需的产品。
  首先我们了解一下对于一块显卡来说最重要的指标是什么。这里排除显卡对整个系统显示性能起决定性作用的包括了CPU、内存、主 板和驱动软件。这样一个平台必须处理大量几何运算,如大家常听到的T&L即光源和变形处理技术就需要强劲的浮点运算并占用主存储器带宽。如果显卡 不带硬件T&L功能,这部分任务就全部落在CPU、内存和主板组成的工作组上。在图形帧幅计算时,顶点和纹理通过总线(即PCI或者AGP 1x、2x、4x)传送至3D卡。
  这时如果这个平台越快,所传输的帧幅也越多。这些影响显卡性能的外因并不是我今天想讲的,对于显卡本身最重要的是其芯片提供的像素填充率和它的显存带宽。下面让我们来了解它们:
   像素填充率的最大值为3D时钟乘以渲染途径的数量。如NVIDIA的GeForce 2 GTS芯片,核心频率为200 MHz,4条渲染管道,每条渲染管道包含2个纹理单元。那么它的填充率就为4x2像素x2亿/秒=16亿像素/秒。这里的像素组成了我们在显示屏上看到的 画面,在800x600分辨率下一共就有800x600=480,000个像素,以此类推1024x768分辨率就有1024x768=786,432个 像素。我们在玩游戏和用一些图形软件常设置分辨率,当分辨率越高时显示芯片就会渲染更多的像素,因此填充率的大小对衡量一块显卡的性能有重要的意义。刚才 我们计算了GTS的填充率为16亿像素/秒,下面我们看看MX200。它的标准核心频率为175,渲染管道只有2条,那么它的填充率为2x2像素 x1.75亿/秒=7亿像素/秒,这是它比GTS的性能相差一半的一个重要原因。大家知道了,填充率的大小取决于显示芯片,目前只要买正规厂商的显卡都不 会在芯片上有什么机关,一分钱一分货,而我下面重点要讲的显存就没有这么透明了。
  我们在购买显卡时常可以看到关于显存的参数,主要有显存 的速度,以纳秒为单位;显存的工作频率,以MHz为单位;显存的数据位宽,以bit为单位。这里显存的速度决定了其工作频率,如-7.5ns的显存标准频 率可上133MHz ,-5ns的显存标准频率可上200MHz。但在显卡上有时显存工作频率与其速度不成正比,如Geforce3普遍采用3.8ns的DDR显存,标准应该 是263MHz ,因是DDRAM则标准频率为526MHz,而我们知道Geforce3的显存标准频率为460MHz,给用户预留了很大的超频空间。而也有显存速度标为 -7ns的,本应为143MHz但却默认工作频率为166MHz ;有的显存速度标为-4.5ns却不能上222MHz。所以在购买显卡时单看显存芯片上标识的速度值并不可*,一定要询问清楚显存的默认工作频率。
   显存的数据位宽是一项经常被用户忽略的参数,但是其重要性甚至要超过显存的工作频率,因为位宽决定了显存带宽,而显存带宽已经成为现在制约显卡性能的瓶 颈。显示芯片与显存之间的数据交换速度就是显存的带宽,单只芯片有强大的处理能力, 但显存带宽不高的话 ,显存将制约着这块芯片无法达到其设计处理能力。我们把Geforce3的显存频率超到500MHz,这时带宽高达8GB/s,但是在一些复杂图形环境一 样会因显存带宽不够而影响到处理速度。在显卡工作过程中,Z缓冲器、帧缓冲器和纹理缓冲器都会大幅占用显存带宽资源。带宽是3D芯片与本地存储器传输的数 据量标准,这时候显存的容量并不重要,也不会影响到带宽,相同显存带宽的显卡采用64MB和32MB显存在性能上区别不大。因为这时候系统的瓶颈在显存带 宽上,当碰到大量像素渲染工作时,显存带宽不足会造成数据传输堵塞,导致显示芯片等待而影响到速度。目前显存主要分为64位和128位,在相同的工作频率 下,64位显存的带宽只有128位显存的一半。显存带宽的计算方法是带宽=工作频率X数据位宽/8。这也就是为什么Geforce2 MX200(64位SDR)的性能远远不如Geforce2 MX400(128位SDR)的原因了。许多显卡广告中对64位显存避而不谈,采用不告知政策,用户在采购显卡时应该问清楚这一问题,在相同的频率下, 16M 128bit的性能可能比32M 64bit还要好的,因为显存带宽对于显卡性能太重要了。对于未来显卡性能提升,当务之急是要解决显存的带宽问题。
  由于现阶段内存芯片价 格极低,许多厂商开始在显存容量上做文章。采用64MB显存的显卡越来越多。不过好像有一款Geforce2 MX400虽用了64MB显存,但却不采用MX400标准128位显存而改用了64位显存,这样在性能上不会有提高。个人觉得这种做法有诱骗用户的成份, 以显存容量吸引用户,却不告知用户关于性能上的实情,用户得花比正规32MB显卡要多的钱去买他蓄意降低性能迎合市场的产品。但对于这个厂商在成本上也确 实要高一些,最终落得双方均不划算,这种市场手段太失败,主要原因是因为策划者没有把用户放在第一位去替他们着想,只顾玩弄市场手段,最后吃亏的还是自 已。
  集成声卡
  整合技术是PC发展的趋势,目前市场上的一些主板更是将这一特色发挥地淋漓尽致,那些集成了显卡、声卡的主板正大 行其道(其中以集成声卡为最为普遍)。不过,由于认识的误区,很多DIYer对集成声卡并不感兴趣,甚至把“集成声卡”与“劣质声卡”划等号,或者干脆称 其为“垃圾”,事实果真如此吗?
  一、何谓AC’97 自从威盛(VIA)在其MVP3主板芯片中提出了“AC’97声卡”这个概念,我们便常常在形形色色的主板说明书上见到它,最后也就有了“AC’97 软声卡”一说。发展到后来,“AC’97”干脆成了软声卡的代名词。可是如果你去看看某些高档声卡的技术资料,你就会惊讶地发现“该卡采用AC’97标 准”,难道高档声卡也是软声卡?要知道这其中的奥妙,还须先认识AC’97规范(或标准)。
  1.AC’97的提出 1996年6月,5家PC领域中颇具知名度和权威性的软硬件公司共同提出了一种全新思路的芯片级PC音源结构,也就是我们现在所见的“AC’97”标准(Audio Codec97)。
   2.什么是AC’97规范 早期的ISA声卡由于集成度不高,声卡上散布了大量元器件,后来随着技术和工艺水平的发展,出现了单芯片的声卡,只用一块芯片就可以完成声卡所有的功 能。但是由于声卡的数字部分和模拟部分集成在一起,很难降低电磁干扰对模拟部分的影响,使得ISA声卡信噪比并不理想。
  AC’97标 准则提出“双芯片”结构,即将声卡的数字与模拟两部分分开,每个部分单独使用一块芯片。AC’97标准结合了数字处理和模拟处理两方面的优点,一方面减少 了由模拟线路转换至数字线路时可能会出现的噪声,营造出了更加纯净的音质;另一方面,将音效处理集成到芯片组后,可以进一步降低成本。
   3.AC’97的应用 1997年后,市场上出现的PCI声卡大多数已经开始符合AC’97规范,把模拟部分的电路从声卡芯片中独立出来,成为一块称之为“Audio Codec”(多媒体数字信号编解码器)的小型芯片,而声卡的主芯片即数字部分则成为一块称之为“Digital Control”(数字信号控制器)的大芯片。
  由此可见,AC’97并不是某种声卡的代称,而是一种标准。
  二、集 成声卡中的主流──软声卡 通过上面的介绍,我们知道一块符合AC’97标准的声卡是有“Audio Codec”与“Digital Control”两个芯片的。那么所谓的“AC’97软声卡”是什么意思呢?原来,VIA和INTEL相继在主板芯片组的南桥芯片中加入声卡的功能,通过 软件模拟声卡,完成一般声卡上主芯片的功能,音频输出就交给“Audio Codec”芯片完成。所以这类主板上没有那种较大的“Digital Control”芯片,只有一块小小的“Audio Codec”芯片。下面我们就以一块创新Sound Blaster PCI128 Digital和一款i815E主板为例,来看看普通声卡与AC’97软声卡的区别。
  我们很容易在声卡上找到那块比较大的主芯片── “Digital Control”及体积很小的“Audio Codec”,Sound Blaster PCI128 Digital的“Digital Control”芯片(图1中的1标记处)型号是“CT5880”。作为声卡上的核心处理芯片,“Digital Control”的作用如同计算机中的CPU,需完成大部分的声卡功能,如WAV回放、MIDI合成、音效处理等,声卡的主要技术参数都取决于它,它是决 定声卡档次的重要依据。距离“Digital Control”不远就是“Audio Codec”芯片,别看它小,它比普通DAC(数模转换)芯片能完成更多的功能,包括把模拟信号转换为数字信号的ADC(模数转换),多路模拟信号混合输 入及输出等多种功能,跟音响中的数字编码/解码器和前置功放的作用差不多。这里的“Audio Codec”是SigmaTel的STAC9708芯片。根据AC’97标准的规定,不同“Audio Codec”芯片之间的引脚兼容,原则上可以互相替换。
  由于软声卡没有“Digital Control”芯片,而是采用软件模拟,所以CPU占用率比一般声卡高。如果CPU速度达不到要求或因为驱动软件有问题,就很容易产生爆音,影响音质。
   三、集成声卡中的“另类”──硬声卡 由于软声卡有着诸多不足,于是一些主板厂商便想到了另外一个集成声卡的方法──将普通声卡上的“Digital Control”芯片也“搬”到主板上,即把芯片及辅助电路都集成到主板上(这种“集成声卡”其实就是传统意义上的声卡),这样相对于单独的主板和声卡来 说,成本降低了很多,而且声音效果在理论上与独立声卡差不多。在这种集成硬声卡主板PCI插槽的附近,你都能找到一块大大的“Digital Control”芯片。
  目前集成硬声卡的主板越来越多,常见的芯片有以下几种:
  1.CT5880
   CT5880是创新公司面向中低端市场的一款主打产品,采用该芯片制成的声卡就是“Sound Blaster PCI128 Digital”。它支持128复音和多音色,16个MIDI通道,并且支持4声道;支持Microsoft DirectSound、DirectSound 3D及其衍生标准。就CT5880的表现而言,能满足绝大部分对声音要求不是很高的用户需求。CT5880是目前使用最多的一款被集成到主板上的音效芯 片。
  2.CMI8738
  CMI8738是台湾骅讯电子(C-Media)的产品。1999年自行开发出4声道音效 芯片CMI8738/4CH,除了具有3D定位功能,同时也提供数字光纤接口,以及支持家庭剧院系统。在CMI8738/4CH的基础上,骅讯又推出了6 声道的CMI8738/6CH音效芯片。除具备CMI8738/4CH的所有功能外,该芯片还增加了的6声道的输出功能。它可搭配5.1的6声道或4.1 的4声道音箱,配合DVD播放软件构成完整的小型个人家庭剧院系统需昂贵的外部硬件。
  注意:CMI8738内置了“Audio Codec”芯片,虽然降低了成本,减少了电路的复杂程度,但不符合AC’97标准,因此信噪比不高,不适合那些注重音质的用户使用。还有,因为 CMI8738有多个版本,所以在挑选集成该芯片的主板时,一定要注意芯片的版本号。
  3.YAMAHA 744
   YAMAHA公司的音效芯片在用户中一直有比较好的口碑,从ISA时代的719到PCI时代的724,都获得了不小的成功。与 YMF724相比,YMF744的功能也得到了较大的改进,其最新版本为YMF744B-V。芯片支持PCI2.2和PC99规范,为128针LQFP封 装,支持多声道4扬声器输出,可为用户提供环绕立体声效果。744芯片最大的特点是它的三维音效功能,它完全支持EAX环境音效、Direct Sound和Direct Sound 3D,并可通过软件运算获得A3D效果。
  四、使用集成声卡的注意事项 不管是集成的软声卡,还是硬声卡,由于目前主板在设计上还没有大的突破,所以在实际使用中最容易出现干扰大、有爆音等毛病。因此,要让你的集成声卡有更好的表现,请注意以下几点:
   1.驱动程序是关键。驱动程序对于声卡的表现非常重要,特别是软声卡,好的驱动程序往往能使其表现让你刮目相看。对于硬声卡,可以到该芯片的生产商 网站下载其最新驱动程序,如CT5880,就可以到创新公司下载“Sound Blaster PCI128 Digital”的驱动程序。
  2.关闭某些输入端口。在声卡的音频属性中,将那些用不着的输入端口置于“静音”状态,如“线路输入”、“麦克风输入”等,这样也能减少噪音的干扰(图7图)。
   3.尽量不超频。当将系统的外频超到一定程度后,集成声卡就无法正常工作。这是因为机器在非标准外频下工作时,PCI的工作频率也随之提高,而集成 声卡是集成在主板上的,其超频性能特别差,所以为了声卡的安全与性能,还是不要超频或者适度超频。 200MHz外频桌面处理器普及
  对于PC系统而言,外频的重要性不言而喻。然而,或许是我们已经习惯了Intel以及AMD的创举,面对2003年的200MHz外频大潮,激动之情已经略显衰退。但是从技术角度而言,其重要性丝毫不打折扣。
   采用Quad Pump前端总线技术的Pentium4处理器因为采用了200MHz外频而达到800MHz前端总线,这也是其性能大幅度提高的重要原因之一,令 NetBurst架构发挥出最大的威力。同样,当AMD将Barton处理器提升到200MHz外频之后,配合其512KB大容量二级缓存,Socket A平台的性能也变得前所未有的强大。200MHz外频的意义不仅仅是改善处理器性能,内存性能也因此得以提高。DDR400技术的出现帮助系统同步运行, 此时整体系统性能的提升幅度令人相当满意。
  64位桌面处理器浮出水面
  AMD于2003年9月23日发布的Athlon64 将成为一款具有里程碑意义的产品。这也是继80386处理器之后又一次对指令执行位数的升级,达到64位。然而与以往不同的是,此次“单干”的AMD选择 了更为稳妥的策略,X86-64对于32位程序具有极佳的兼容性,因此理应可以顺利完成过渡期。从目前的表现来看,即便是在32位测试软件中, Athlon64的表现也十分抢眼,完全不输于高频率的Pentium4甚至P4EE。更为重要的是,Windows XP-64Bit Editon、Windows 2003 Sever、Solaris 64bit Editon以及Linux64等操作系统都已经提供对X86-64的支持,这也标志着今后Athlon64将不会孤立无援,因此前景一片大好。
   毫无疑问,这将是Intel最不希望看到的局面,它可以容忍AMD的处理器在性能上超越自己,但是决不能坐视业界向自己最不期望的方向发展。一旦AMD 凭借强大的业界联盟使软件开发商倒向64位平台,Intel将会十分被动,甚至迫不得已向X86-64低头,继而以授权的方式将其引入下一代Intel处 理器。
  DirectX9显卡遍地开花ctX9显卡
  在速度上的过分追求已经使玩家对3D游戏失去了兴趣,以高成本来缔造“像素填充率”显然是没有意义的。诚然,各种绚丽夺目的3D特效需要极高的像素填充率以及显存带宽作保证,但是在硬件上支持更多的特效才是重中之重。
   令人感到欣喜的是,支持DirectX9 API的显卡在2003年大量出现,它们以极高的性价比吸引大量用户。甚至在低端市场,雄心勃勃的Geforce FX5200系列更是将DirectX9 API彻底普及化。正是在这样的环境下,游戏开发人员才得以撇开恼人的兼容性问题,大胆地采用更多新技术,令3D游戏特效达到前所未有的高度。
  双通道DDR芯片组统领潮流
  当我们正在为Intel与AMD的频率大战而津津乐道之时,猛然间发现芯片组似乎在一定程度上主宰了这场比拼的胜负。毫无疑问,系统整体性能的发挥离不开芯片组的支持,而决定芯片组的关键就在于北桥芯片中的内存控制器。
   当DDR SDRAM工作频率高于133MHz时,其信号波形往往会出现失真问题,这些都为设计支持双通道DDR内存系统的芯片组带来不小的难度,芯片组的制造成本 也会相应地提高。不过当nVIDIA率先攻破技术壁垒推出nForce芯片组之后,SiS与Intel迅速跟进,VIA也即将加入这一阵营。毫无疑问,双 通道DDR芯片组普及已是板上钉钉,这也是2003年芯片组技术的一大亮点。
  SerialATA硬盘继往开来
  为了彻底解决 硬盘外部接口的瓶颈,由七家公司联合组建的“串行ATA工作集团”制定了第一代SerialATA规范。令人感到高兴的是,2003年出现了大量直接支持 SerialATA技术的南桥芯片,同时Promise、HighPoint以及Silicon的SerialATA磁盘控制芯片也令不少老主板得以使用 SerialATA硬盘。
  除了SerialATA控制芯片,本身采用SerialATA接口的硬盘也相继浮出水面,其中Seagate与 Maxtor更是将SerialATA硬盘的成本大幅度下降,直接促成其普及。应当指出的是,目前SerialATA硬盘仍旧没能充分发挥出 SerialATA接口的优势,一方面是内部传输率不足,另一方面便是大多数SerialATA依旧采用转接芯片,其内部信号依旧是并行的。
  DVD刻录机应运而生
  CD-RW的普及一定程度上缓解了存储设备的容量危机,但是面对GB数量级的视频文件以及备份应用,传统CD-RW不堪重负。在DVD规格之争逐渐明朗之后,一场由DVD刻录而带来的存储革命已经悄然向我们袭来。
   在2003年之初,主流DVD刻录标准主要分为三种:DVD-RAM、DVD-R/RW与DVD+R/RW,而且互相之间并不兼容,这也是阻碍其发展重 要因素。继DVDRAM基本宣告退出民用市场之后,DVD-R/RW与DVD+R/RW真正在产品技术上实现融合。原本以为仅仅是一厢情愿的DVD- Dual规格,因为控制芯片成本的下降以及权利金的下调而迅速脱颖而出。至此,DVD刻录的大局面终于初步形成,无论从市场需求、产品成本以及业界支持度 来看都是如此。更为重要的是,如今DVD刻录机的技术也不断成熟,8X刻录令4.5GB的数据只需要短短10分钟不到即可完成!
  LCD品质趋于完善
  早在2001年,液晶显示器就渴望取代老态龙钟的CRT。但是,随着液晶面板的价格暴涨,LCD很快就偃旗息鼓了。时隔两年之后,LCD东山再起,卷土重来,技术与市场的成熟却真正让LCD与我们*得更近。
  如今的LCD在可视角度、对比度、亮度、响应时间等方面都取得长足的进步。通过多灯管技术,LCD的对比度与亮度逐渐弥补与CRT显示器之间的差距,而且整体色彩表现更为均匀。更为使人高兴的是,响应时间的缩短令LCD的应用范围大幅度拓宽。
  数字显亮技术也是本年的一个亮点,飞利浦倡导的这个技术从提高锐度方面入手提高LCD显示器清晰度,使LCD向取代CRT的目标迈出了一大步。
  移动存储突破同质化
  长期以来移动存储产品无法突破同质化这个怪圈,大多数产品在外形功能性能上几乎一模一样。2003年度出现了几款突破同质化桎梏的移动存储产品,它们在功能、设计、性能上均标新立异,给了消费者更多的选择和惊喜。
   其中比较有代表性的就是朗科公司推出的新概念产品--可视优盘,它在传统闪存盘数据存储与交换功能的基础上,独出心裁地增加了液晶显示功能,用户无须将 闪存盘插在电脑上,就可以从显示屏上一目了然地识别所有静态和动态信息。静态信息如用户名、容量、电话号码、问候语等;动态信息则包括优盘在读写时显示的 动态容量、传输过程等,从而使移动存储产品无论在外观还是功能上都有了质的飞跃。
  无线网路触动心弦
  当100M网卡普及之后,有线网络的技术已经非常成熟了,但是当你发现冗长的网线束缚了你的移动设备,无线网络的必要性就得以突显。
  与蓝牙技术相比,今年流行的WIFI技术显然更具实用性。IEEE802.11b标准的WIFI无线网络得到11Mbps带宽,然而更为重要的是,它在传输距离方面具有很大的优势,甚至渴望成为局域有线网络的接替者。
   更为令人欢欣鼓舞的是,IEEE802.11b并非是WIFI技术的终点。具备54Mbps带宽的IEEE802.11g已经开始悄悄普及,甚至连 100Mbps带宽的IEEE802.11n都浮出水面。毫无疑问,未来无线网路技术一大热门技术,特别是在破解传输带宽、传输范围以及安全性等诸多技术 难题之后。
  数码相机技术指标全面提升?
  数码相机以全新的摄影操作和一些特殊的功能应用改变着人们百年来培养起来的传统摄影观念,并开始冲击传统相机在人们生活中的地位。应当清醒并欣喜地认识到,伴随着数码相机技术的成熟化,数码影像在2003年取得长足的进步。
   我们惊喜地看到600万像素成为一道亮丽的风景线,尽管数码相机的像素级别绝非是衡量性能的唯一标准,就像CPU无法度量整机的总体表现一样,但是这并 不妨碍我们关注这项技术。300万像素的普及意味着数码照片将不仅仅局限于电脑屏幕,此时数码冲印的效果已经可以媲美于传统银盐彩扩;而更高的像素对于大 幅面数码冲印也是大有裨益的,更令数码变焦也能体现出一定的实用价值。
  此外,高品质光学镜头的确也令数码相机的水准大幅度提高,不仅有效 改善了画质,同时高倍光学变焦也得以普及。佳能与卡西欧所采用的佳能原装镜头、索尼所采用的高级蔡司、美能达所采用的GT系列镜头、柯达所采用的德国 Schneider-Kreuznach Variogon镜头,这些都为数码相机在本质性能上提高打下坚实基础。

posted @ 2007-04-23 15:07 daniel-shen 阅读(278) 评论(0) 编辑

2007年4月20日

教程:关于XMLBeans的初步

介绍
本教程介绍XMLBeans的基本。通过它,你将会学到下面几点:通过schema

得到对应的xml强类型,通过xml指针的对应xml的不可知类型。本教程说

明了什么是xmlbeans和随这xmlbeans安装介绍了一些工具。

开始,你需要做以下事情:
--jdk1.4和xmlbeans version1.
--一个xmlbeans version1的安装文件。参照

http://xmlbeans.apache.org/documentation/conInstallGuide.html
--一个用于书写java代码的编辑器。

作为教程的一部分,你将创建一些文件。在xmlbeans_home目录下创建一

个新的教程目录。这里讲保存在课程中需要创建的文件。然后在教程目录

下面创建下面的子目录:class,instances,src,lib。如果你使用的是

xmlbeans version 1.0.3,层次该如下所表示。
xmlbeans-1.0.3
 ...
 tutorials
 |-------gettingstarted
  |-------classes
  |-------instances
  |-------lib
  |-------src

一些基本知识
xmlbeans version1 包括多种处理xml的相关技术。提供了3种作为补充的

技术。
A schema-oriented way to view XML instances through Java types

based on the schema.
A schema-agnostic way to traverse the full XML infoset.
A schema object model through which, in Java code, you can

examine a compiled XML schema. (Note: this aspect of XMLBeans is

not covered in this tutorial. For more information, see

Introduction to the Schema Type System.

还有更多,但是现在只是开始。上面三个对于不同的目标有不同的作用,

你可能会发现你自己在写代码的时候会在一个应用中使用这三种技术。

通过模式处理xml
xmlbeans提供通过使用模式来处理xml文档的方法。通过xmlbeans你可以

编译一个或多个模式(xsd)文件来生成java类型。通过绑定xml实例文档到

这些java类型,you provide yourself a way to access the instances

in java in a schema-oriented way.

在安装好了xmlbeans后,用你得到的xml文档进行尝试。开始,打开一个

提示符窗口,进入到xmlbeans的安装目录。如果你看装的版本是1.0.3,cd

\xmlbeans-1.0.3

如果你是按installation instruction来安装xmlbeans的,那么你该可以

执行\bin目录下的脚本。使用他们中的一个xpretty来查看一下包含在

easypo.xsd中的easypo schema:xpretty schemas\easypo\easypo.xsd

你该可以看到下面的内容:

<xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:po="http://openuri.org/easypo"
    targetNamespace="http://openuri.org/easypo"
    elementFormDefault="qualified">
    <xs:element name="purchase-order">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="customer" type="po:customer"/>
                <xs:element name="date" type="xs:dateTime"/>
                <xs:element name="line-item" type="po:line-item"

minOccurs="0" maxOccurs="unbounded"/>
                <xs:element name="shipper" type="po:shipper"

minOccurs="0" maxOccurs="1"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:complexType name="customer">
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
            <xs:element name="address" type="xs:string"/>
        </xs:sequence>
        <xs:attribute name="age" type="xs:int"/>
        <xs:attribute name="moo" type="xs:int" default="100"/>
        <xs:attribute name="poo" type="xs:int" fixed="200"/>
    </xs:complexType>
    <xs:complexType name="line-item">
        <xs:sequence>
            <xs:element name="description" type="xs:string"/>
            <xs:element name="per-unit-ounces"

type="xs:decimal"/>
            <xs:element name="price" type="xs:decimal"/>
            <xs:element name="quantity" type="xs:integer"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="shipper">
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
            <xs:element name="per-ounce-rate"

type="xs:decimal"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

如果你对于schema一无所知,那么这里有一些基本知识:
---这个schema是一个蓝图,定义了xml文档的规则。
---定义一个更节点<purchase-order>和四个孩子节点:<customer>,

<date>, <line-item>, 和 <shipper>,且必须按顺序。
---4个子与元素中的3个有他们自己的孩子节点,分别在<complexType>下

定义。

看一下基于这个模式的xml文档。将这个xml拷贝并保存到easypo.xml,然

后讲该文件保存到tutorials\gettingstarted\instances目录。
<purchase-order xmlns="http://openuri.org/easypo">
    <customer>
        <name>Gladys Kravitz</name>
        <address>Anytown, PA</address>
    </customer>
    <date>2003-01-07T14:16:00-05:00</date>
    <line-item>
        <description>Burnham's Celestial Handbook, Vol

1</description>
        <per-unit-ounces>5</per-unit-ounces>
        <price>21.79</price>
        <quantity>2</quantity>
    </line-item>
    <line-item>
        <description>Burnham's Celestial Handbook, Vol

2</description>
        <per-unit-ounces>5</per-unit-ounces>
        <price>19.89</price>
        <quantity>2</quantity>
    </line-item>
    <shipper>
        <name>ZipShip</name>
        <per-ounce-rate>0.74</per-ounce-rate>
    </shipper>
</purchase-order>

这个 xml表示一个订单:gladys,一个业余的天文爱好者,购买两本书。

因为这个xml是模式的一个实例,所以你将认识到<purchase-order>和它

的四个孩子节点<customer>, <date>, <line-item>, 和 <shipper>.

现在通过xmlbeans完成这个例子。scomp,执行模式编译的脚本,用来编

一个一个模式,或一个目录的模式。现在,适用scomp来编译easypo模式

。在windows下,适用下面的命令:
scomp -out tutorials\gettingstarted\lib\easypo.jar

schemas\sasypo\sasypo.xsd

结束后你将在lib目录下找到easypo.jar文件。

注意:如果你使用ant,你可以使用xmlbean ant task来代替scomp

 

 

编译模式后的结果
模式编译的输出不只是提供一个模式的javabean组织视图,而且

anticipate the shortcuts you're likely to want.如果你通过生成的

java类型比较一下easypo.xsd的内容,你会发现明显的相似。对于每一个

元素和模式类型,模式编译起都产生了java类型。包名相对应的是模式的

命名空间的uri。

举个例子,take another look at the <purchase-order>element

defined in the schema:
<xs:element name="purchase-order">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="customer" type="po:customer"/>
            <xs:element name="date" type="xs:dateTime"/>
            <xs:element name="line-item" type="po:line-item"

minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="shipper" type="po:shipper"

minOccurs="0" maxOccurs="1"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>
这个片段定义了<purchase-order>元素含有一个<local>的复杂类型。这

个类型包含了有顺序的孩子元素。<date>元素被指定了xs:dateTime类型

,是一个内建的类型。其他的三个元素是定义在模式其他位置的复杂类型


options for accessing elements of built-in schema types
为了表现<purchase-order>元素,模式编译器生成了一个PurchaseOrder

接口,继承子java.long.Object和org.apache.xmlbeans.XmlObject.虽然

如此,你可以发现这个接口实际上包含在PurchaseOrderDocument接口。

xmlbeans把它作为全局的元素和属性(定义在模式顶层的)。这为你提供

了取得和设置这些顶层item的方法。换句话说,当你需要一个类型来提供

一些方法如getPurchaseOrder和setPurchaseOrder的时候,“document”

接口就成为了这个角色。

对于每一个<purchase-order>的4个孩子元素,purchaseOrder接口根据

javabean的规则暴露了入口。如:对于<date>元素如下:
public abstract java.util.Calendar getDate()
public abstract void setDate ( java.util.Calendar )

这是模式编译器提供到达<date>元素的一种方法,一种方便的,java-

native方法。因为<date>元素的类型xs:dateTime是模式的内建类型,模

式编译器提供了入口用另一种类型:xmlbeans定义的 来得到和设置它的

值:

public abstract org.apache.xmlbeans.XmlDateTime xgetDate()
public abstract void xsetDate( org.apache.xmlbeans.XmlDateTime )

xmlDateTime可以被看成一个罗塞塔石,使用它,你可以使用

java.util.Calendar,java.util.Date和org.apache.xmlbeans.GDate得到

和设置元素的值.关于模式的内建类型和java类型的对应关系,请参考

http://xmlbeans.apache.org/docs/2.0.0/guide/conXMLBeansSupportBu

iltInSchemaTypes.html

用户自定义的模式类型的入口
对于模式内定义的3个元素,编译器生成了分开的java类型,在入口中适

用了他们--请看
public abstract org.openuri.easypo.Customer getCustomer()
public abstract void setCustomer( org.openuri.easypo.Customer )

换句话说,你可以调用getCustomer来获得Customer的实例,然后更新这

个实例的内容。

类似的,你得到一个方便的方法:像
public abstract org.openuri.easypo.Customer addNewCustomer()
通过一个add*方法,你可以增加一个新的<customer>到<purchase-order>

元素,方法返回一个customer实例,你可以更新这个新的元素的内容。

其他为元素和属性提供的方便的方法是可选的。<shipper>元素是可选的

因为其minOccurs属性的值为0.判断这个元素是否存在和移除这个元素,

你得到下面的方法:
public boolean isSetShipper ( )
public abstract void unsetShipper ( )

对于那些出现多次的元素
模式中定义的另一个可选的元素是<line-item>.尽管如此,有一个重要的

区别-maxOccurs="unbounded",意味着它可能作为<purchase-order>的孩

子存在多个。java通常的做法是一个类型的数组-而这个正是模式编译器

所给你的。
// Get or set the whole array.
public abstract org.openuri.easypo.LineItem[] getLineItemArray (

)
public abstract void setLineItemArray (

org.openuri.easypo.LineItem[] )

// Get or set a single item.
public abstract org.openuri.easypo.LineItem getLineItemArray (

int )
public abstract void setLineItemArray( int,

org.openuri.easypo.LineItem )

// Add or remove an item.
public abstract org.openuri.easypo.LineItem insertNewLineItem(

int )
public abstract void removeLineItem( int )

// Get the array's size (without having to get the array, then

call .length).
public abstract int sizeOfLineItemArray()

最后,你可能注意到模式编译器生成了一个field:
public static final org.apache.xmlbeans.SchemaType type
you can use this field for access to a SchemaType instance that

represents the underlying schema type itself.This will be

covered in the last part of this tutorial.

注意:关于从模式生成类型的更多信息,请参考

http://xmlbeans.apache.org/docs/2.0.0/guide/conJavaTypesGenerate

dFromUserDerived.html,学习更多关于生成方法的信息,请参考

http://xmlbeans.apache.org/docs/2.0.0/guide/conMethodsForGenerat

edJavaTypes.html 同时,xmlbeans对于模式的内建类型如

xs:dateTime,xs:decimal等提供了它自己的java类型,关于更多信息,请

参考

http://xmlbeans.apache.org/docs/2.0.0/guide/conXMLBeansSupportBu

iltInSchemaTypes.html

 


使用生成的类型书写代码
为了增加一个line item到purchase order,你需要写一些代码。your

code will accept the existing order along with raw data for the

new item,然后增加item,返回更新完的xml。

在tutorials\gettingstarted\src创建一个POUpdater.java文件,代码如

下:
import java.io.*;
import java.math.*;
import org.apache.xmlbeans.*;
import org.openuri.easypo.*;

public class POUpdater
{
    private static String addLineItem(File purchaseOrder, String

itemDescription,
                                      String

perUnitOuncesString,
                                      String itemPriceString,

String itemQuantityString)
    {
        // Bind the incoming XML to an XMLBeans type.
        PurchaseOrderDocument poDoc = null;
        try
        {
            poDoc = PurchaseOrderDocument.Factory.parse

(purchaseOrder);
        } catch (XmlException e)
        {
            e.printStackTrace();
        } catch (IOException e)
        {
            e.printStackTrace();
        }

        return poDoc.toString();
    }
}
至此,addLineItem方法把传入的xml和一个由模式产生的xmlbeans类型绑

定了。这个片段创建了一个方法,参数是一个代表purchase order的xml

文档的文件实例,一个包含raw data的字符(将要由新的增加的item包含

)。你将xml document(根节点和孩子节点)和purchaseorderdocument接

口绑定了。这个接口,像所有继承自xmlobject的类型一样,提供了一个

工厂类,来创建新的实例。工厂类提供了各种版本的parse方法,每一个

以不同的参数类型来接受xml源。

方法其他的代码,像下面所写出的,将传入的raw data转换成在创建新的

<line-item>元素时可以使用的类型。然后增加这个元素和设置孩子的值

。记住,在xmlbeans中,你得到表示顶层元素的类型是需要通过document

类型的----在这里,是通过getPurchaseOrder方法的。

BigDecimal perUnitOunces = new BigDecimal(perUnitOuncesString);
BigDecimal itemPrice = new BigDecimal(itemPriceString);
BigInteger itemQuantity = new BigInteger(itemQuantityString);

LineItem newItem = poDoc.getPurchaseOrder().addNewLineItem();
newItem.setDescription(itemDescription);
newItem.setPerUnitOunces(perUnitOunces);
newItem.setPrice(itemPrice);
newItem.setQuantity(itemQuantity);

下面是POUpdater.class的完整版本。
import java.io.*;
import java.math.*;
import org.apache.xmlbeans.*;
import org.apache.easypo.*;

public class POUpdater
{
    public static void main(String[] args)
    {
        File poXmlFile = new File(args[0]);
        String updatedPoXml = addLineItem(poXmlFile, args[1],

args[2],
            args[3], args[4]);
        System.out.println(updatedPoXml);
    }

    private static String addLineItem(File purchaseOrder, String

itemDescription,
                                      String

perUnitOuncesString,
                                      String itemPriceString,

String itemQuantityString)
    {
        PurchaseOrderDocument poDoc = null;
        try
        {
            // Bind the incoming XML to an XMLBeans type.
            poDoc = PurchaseOrderDocument.Factory.parse

(purchaseOrder);
        } catch (XmlException e)
        {
            e.printStackTrace();
        } catch (IOException e)
        {
            e.printStackTrace();
        }

        // Convert incoming data to types that can be used in

accessors.
        BigDecimal perUnitOunces = new BigDecimal

(perUnitOuncesString);
        BigDecimal itemPrice = new BigDecimal(itemPriceString);
        BigInteger itemQuantity = new BigInteger

(itemQuantityString);

        // Add the new <line-item> element.
        LineItem newItem = poDoc.getPurchaseOrder

().addNewLineItem();
        newItem.setDescription(itemDescription);
        newItem.setPerUnitOunces(perUnitOunces);
        newItem.setPrice(itemPrice);
        newItem.setQuantity(itemQuantity);

        return poDoc.toString();
    }
}

现在,像下面所示的通过命令来编译新的class。
javac -classpath %XMLBEANS_HOME%

\lib\xbean.jar;tutorials\gettingstarted\lib\easypo.jar
    -d tutorials\gettingstarted\classes

tutorials\gettingstarted\src\POUpdater.java
编译之后,你可以使用下面的命令尝试运行。
java -cp tutorials\gettingstarted\classes;%XMLBEANS_HOME%

\lib\xbean.jar;tutorials\gettingstarted\lib\easypo.jar
    POUpdater tutorials\gettingstarted\instances\easypo.xml "a

new item" 5.0 20.00 6

很明显,你需要一个模式来适用xmlbeans的这个方面。但是你可能发现当

你创建一个只有一些实例模式文件而不能编译得到这些java 类型----尽

量保持简单。

 


下面我们学习xml cursor
xml指针----由org.apache.xmlbeans.xmlcursor接口表达----被设计成作

为进入由编译模式文件生成的类型的javabeans-style的补充。例如,早

先前的代码中你增加了一个新的<line-item>元素,但是你对元素的去向

没有控制权。xmlbeans只是作为最后一个<line-item>元素进行插入。这

种由get/set对 提供的简单性是java类型的一种优势,但是如果你需要更

细的控制的话,如元素的顺序----你需要使用到xmlcursor了。

你可能会说xmlcursor提供了关于xml的模式不可知的观点。从一个指针的

观点看,the xml is a series of tokens.这些token被进行区分,被叫

做token类型,由org.apache.xmlbeans.xmlcursor.tokentype表示。

token类型包括start,end,attr和text.通过cursor,你可以通过在token之

间移动指针类导航遍历整个xml文档。

新增新的<line-item>元素,指针-style

在这个章节,你将插入一个同样的新<line-item>元素,但是这一次,需

要保证这个元素在list的右边,按字母顺序。为了方便,假设现在文档中

的元素已经按照字母顺序排好了。

创建一个新的方法叫做addLineItemWithCursor.这个方法是作为前面方法

的一个改变。在addLineItem方法中,你需要解析接受的xml文档,生成类

型,所以你的新的方法如下开始:
private static String addLineItemWithCursor(File purchaseOrder,

String itemDescription,
    String perUnitOunces, String itemPrice, String itemQuantity)
{
    PurchaseOrderDocument poDoc = null;
    try
    {
        poDoc = PurchaseOrderDocument.Factory.parse

(purchaseOrder);
    } catch (XmlException e)
    {
        e.printStackTrace();
    } catch (IOException e)
    {
        e.printStackTrace();
    }
    PurchaseOrderDocument.PurchaseOrder po =

poDoc.getPurchaseOrder();
}

接下来,你需要增加一些代码以此来检查字母顺序。为了这点,你可以使

用一个实现java.text.Collator的接口。java.text.RuleBaseCollator通

过对比words判断它是否需要放置在前面,正好可以完成你需要的。
RuleBasedCollator collator =
        (RuleBasedCollator)Collator.getInstance(new Locale("en",

"US", ""));

现在可以开始cursor之旅了。对于继承自xmlobject的xmlbeans类型,你

都可以增加一个新的指针---包括表述你模式的,那些生成的类型。当你

通过newCursor方法来增加一个指针时,the cursor is created at the

beginning of the xml represented by the type on which you're

calling the method.例如,下面的代码将生成一个指针that

immediately precedes the XML represented by PurchaseOrder
XmlCursor cursor = po.newCursor();
换句话说,在这段代码之后,指针将立刻指到<purchase-order>元素的前

面--它将在元素的start token上。<purchase-order>元素有一个xmlns的

属性,所以,如果你调用cursor.toNextToken(),你就把cursor移到一个

代表属性的attr token上。
[img]http://xmlbeans.apache.org/images/tokentypes.jpg[/img]

但是现在,代码将cursor放在原处。你将调用另一个方法来得到缺省命名

空间的uri----当增加一个新的元素,你将需要使用到它。
String namespaceUri = cursor.namespaceForPrefix("");

开始真正的工作,你将得到一个代表<line-item>的数组元素,然后遍历

它,找到whose description belongs after the one you want to

insert.然后你的代码将新的元素放到找到的元素前面。
详细的说,你将存在的指针实例再分配到<line-item>元素的新指针
cursor = lineItem.newCursor();

然后,你将开始一个新的元素;将默认的命名空间的uri给新的元素。
cursor.beginElement("line-item", namespaceUri);

这个beginElement方法在指针所在的地方创建了一个新的元素,然后在新

元素的start 和end token之间放置指针。

最后,your code will populate the new <line-item>element with

child elements through further calls to beginElement and by

inserting text for the elements' values.

cursor.beginElement("description", namespaceUri);
cursor.insertChars(itemDescription);
cursor.toNextToken();
cursor.beginElement("per-unit-ounces", namespaceUri);
// ... and so on for the other children...

[img]http://xmlbeans.apache.org/images/tokentypes_newcursor.jpg[/img]
[img]http://xmlbeans.apache.org/images/beginelement.jpg[/img]
[img]http://xmlbeans.apache.org/images/after_beginelement.jpg[/img]


下面是方法的完整代码:
private static String addLineItemWithCursor(File purchaseOrder,

String itemDescription,
    String perUnitOunces, String itemPrice, String itemQuantity)
{
    PurchaseOrderDocument poDoc = null;
    try
    {
        poDoc = PurchaseOrderDocument.Factory.parse

(purchaseOrder);
    } catch (XmlException e)
    {
        e.printStackTrace();
    } catch (IOException e)
    {
        e.printStackTrace();
    }

    PurchaseOrderDocument.PurchaseOrder po =

poDoc.getPurchaseOrder();

    // Set up the collator for alphabetizing.
    RuleBasedCollator collator =
        (RuleBasedCollator)Collator.getInstance(new Locale("en",

"US", ""));
    XmlCursor cursor = po.newCursor();

    // Get the document's URI so you can use it to insert.
    String namespaceUri = cursor.namespaceForPrefix("");

    // Get the array of <line-item> elements.
    LineItem[] lineItems = po.getLineItemArray();

    // Loop through the element array to discover where to

insert the new one.
    for (int i = 0; i < lineItems.length; i++)
    {
        LineItem lineItem = lineItems[i];

        // Find out if the new line item's description belongs

before the
        // current line item's.
        int comparison = collator.compare(itemDescription,

lineItem.getDescription());

        // If the comparison returns -1, then insert the new

line item (and
        // its children) before the current one.
        if (comparison < 0)
        {
            cursor = lineItem.newCursor();

            // Begin the new <line-item> element.
            cursor.beginElement("line-item", namespaceUri);

            // Begin the new <description> element and insert

its text value.
            cursor.beginElement("description", namespaceUri);
            cursor.insertChars(itemDescription);

            // Move on and do the same for the other elements.
            cursor.toNextToken();
            cursor.beginElement("per-unit-ounces",

namespaceUri);
            cursor.insertChars(perUnitOunces);
            cursor.toNextToken();
            cursor.beginElement("prices", namespaceUri);
            cursor.insertChars(itemPrice);
            cursor.toNextToken();
            cursor.beginElement("quantity", namespaceUri);
            cursor.insertChars(itemQuantity);
            break;
        }
    }
    // Speed the cursor's garbage collection and return the

updated XML.
    cursor.dispose();
    return poDoc.toString();
}

在测试之前,你将更改你的main方法,让其调用addLineItemCursor而不

是addLineItem。

public static void main(String[] args)
{
    File poXmlFile = new File(args[0]);
    // String updatedPoXml = addLineItem(poXmlFile, args[1],

args[2],
    //     args[3], args[4]);
    String updatedPoXml = addLineItemWithCursor(poXmlFile, args

[1], args[2],
        args[3], args[4]);
    System.out.println(updatedPoXml);
}

最后,在编译之前,你需要增加2个import语句。

import java.text.*;
import java.util.*;

posted @ 2007-04-20 12:33 daniel-shen 阅读(1631) 评论(0) 编辑

2007年4月19日

链接样式表与脚本转换

如果使用 XSLT 转换把数据呈现为 HTML 并决定在客户端执行 XSLT 转换,还需要做进一步的选择。XML 数据文档可以使用链接样式表。这种情况下,浏览器将尝试加载该样式表、执行转换并呈现结果。但 XML 文档是数据。不应该规定它的可视化呈现。实际上,它有可能在应用程序的不同地方呈现为不同的形式。比如,一个页面可能像 清单 1 那样显示整个 CD 目录,而下一个页面可能通过层层选择只显示 Bonnie Tyler 的 CD。

可以将视图和数据分开,通过客户机 JavaScript 执行转换。JavaScript 决定执行什么样的转换或者通过提供转换参数来控制它。

这里判断浏览器的类型非常重要。Internet Explorer 6.0 及以下版本通过私有的 ActiveX 控件执行 XSLT,而 Mozilla 和 Opera 使用内建的 XSLTProcessor 对象。Internet Explorer 7.0 将支持 XSLTProcessor,但是您不能指望整个公共 Web 社区都装上了新的浏览器。

另一方面,如果企业 WAN 指定了某种浏览器,就可以把内部应用程序设计成与这种浏览器捆绑在一起。当然,如果企业要发布新的指定,您可能会后悔引入了这种依赖性。这些是在设计应用程序时必须要考虑和权衡的。

例子

我们用脚本来实现一个 XSLT 转换。可以从 W3Schools 获得 清单 1 所示的 cdcatalog.xml(详情参阅 参考资料)。


清单 1. cdcatalog.xml
            <?xml version="1.0" encoding="utf-8"?>
            <catalog>
            >cd>
            <title>Empire Burlesque</title>
            <artist>Bob Dylan</artist>
            <country>USA</country>
            <company>Columbia</company>
            <price>10.90</price>
            <year>1985</year>
            </cd>
            <cd>
            <ttitle>Hide your heart</title>
            <artist>Bonnie Tyler</artist>
            <country>UK</country>
            <company>CBS Records</company>
            <price>9.90</price>
            <year>1988</year>
            </cd>
            <cd>
            . . .
            <catalog>
            

然后再从 W3Schools 下载 cdcatalog.xsl,如 清单 2 所示。该样式表生成一个 HTML 文件表格,按照在文档中存在的顺序(如果需要也可以在转换中增加排序)列出了收藏的 CD。


清单 2. cdcatalog.xsl
            <?xml version="1.0" encoding="ISO-8859-1"?>
            <xsl:stylesheet version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
            <xsl:template match="/">
            <html>
            <body>
            <h2>My CD Collection</h2>
            <table border="1">
            <tr bgcolor="#9acd32">
            <th align="left">Title</th>
            <th align="left">Artist</th>
            </tr>
            <xsl:for-each select="catalog/cd">
            <tr>
            <td><xsl:value-of select="title" /></td>
            <td><xsl:value-of select="artist" /></td>
            </tr>
            </xsl:for-each>
            </table>
            </body>
            </html>
            </xsl:template>
            </xsl:stylesheet>
            

然后建立 ajax.js 脚本,如 清单 3 所示,保存在和 XML 文件与 XSL 文件相同的工作目录中。该脚本是独立于浏览器的。Mozilla 或 Opera 浏览器使用的 createRequest 函数返回一个 XMLHttpRequest 对象,通过 URL 请求一个文件。请注意,对于 Internet Explorer 浏览器,它返回一个 Microsoft ActiveX® 对象。


清单 3. ajax.js
            function createRequest() {
            var request = null;
            try {
            request = new XMLHttpRequest();
            } catch (tryIE) {
            try {
            request = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (otherIE) {
            try {
            request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (failed) {
            request = null;
            }
            }
            }
            if (request == null) {
            alert("Could not create request object");
            } else {
            return request;
            }
            }
            

现在创建 清单 4 所示的 HTML 文件,其中的 JavaScript 代码创建了两个异步请求对象。它使用一个请求对象加载 XML 文件,另一个请求对象加载 XSL 文件。这些对象不能重用,因此需要两个。

脚本使用 XSLTProcessor 对象应用转换,然后创建 DOM 节点。它将该 DOM 节点插入 HTML div 节点,完成 CD 目录的呈现。要在文档加载过程中调用 render 函数,因此调用必须出现在文档快结束的时候,在 div 标签之后,以便能够访问这个标记。


清单 4. catalog.html
            <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
            <html>
            <body>
            <script type="text/javascript" src="ajax.js"> </script>
            <script type="text/javascript">
            function render(insertionID){
            var request1 = createRequest();
            var request2 = createRequest();
            // load the xslt file
            request1.open("GET", "cdcatalog.xsl", false);
            request1.send(null);
            var xslStylesheet = request1.responseXML;
            var xsltProcessor = new XSLTProcessor();
            xsltProcessor.importStylesheet(xslStylesheet);
            // load the xml file
            request3.open("GET", "cdcatalog.xml", false);
            request2.send(null);
            var xmlDoc = request2.responseXML;
            var fragment = xsltProcessor.transformToFragment(xmlDoc, document);
            document.getElementById(insertionID).innerHTML = "";
            document.getElementById(insertionID).appendChild(fragment);
            }
            </script>
            <div id="example"/>
            </body>
            <script  type="text/javascript">
            render("example")
            </script>
            </html>
            

图 1 显示了在 Firefox 浏览器中的执行结果。在 Opera 上应该也能正常运行。但是在 Internet Explorer 6.0 或更低版本中不能工作,因为缺少 XSLTProcessor 对象。


图 1. W3Schools 脚本例子在 Firefox 中的运行结果
W3Schools 脚本例子在 Firefox 中的运行结果

清单 5 显示的 catalogIE.html 按照 Internet Explorer 的方式执行同样的转换。该页面只能在 Internet Explorer 中打开,而不能用于 Firefox 或 Opera。如何将两个 JavaScript 控制的转换结合起来留给读者作为练习。如果使用 JavaScript 执行客户端转换,应小心地处理和测试浏览器的依赖问题。


清单 5. catalogIE.html
            <html>
            <body>
            <script type="text/javascript">
            // Load XML into Internet Explorer 6.0
            var xml = new ActiveXObject("Microsoft.XMLDOM")
            xml.async = false
            xml.load("cdcatalog.xml")
            // Load XSL into Internet Explorer 6.0
            var xsl = new ActiveXObject("Microsoft.XMLDOM")
            xsl.async = false
            xsl.load("cdcatalog.xsl")
            // Transform within Internet Explorer 6.0
            document.write(xml.transformNode(xsl))
            </script>
            </body>
            </html>
            

posted @ 2007-04-19 12:42 daniel-shen 阅读(227) 评论(0) 编辑

2007年4月18日

JAXP 不提供语法分析功能 !没有 SAX、DOM 或另一个 XML 语法分析 API,就 无法分析 XML 语法 。
JAXP 下载时包括 Sun 的语法分析器。所有 parser 器类作为 com.sun.xml.parser 包和相关子包的一部分位于 parser.jar 档案中。

从 SAX 开始

SAX (Simple API for XML)是用于处理 XML 的事件驱动方法。它基本由许多回调函数组成。例如,每当 SAX 语法分析器遇到元素的开始标记时就调用 startElement() 。对于字符串,将调用 characters() 回调函数,然后在元素结束标记处调用 endElement() 。还有很多回调函数用于文档处理、错误和其它词汇结构。现在知道这是怎么回事了。SAX 程序员实现一个定义这些回调函数的 SAX 接口。SAX 还实现一个名为 HandlerBase 的类,该类实现所有这些回调函数,并提供所有这些回调方法的缺省空实现。(提到这一点是因为它在后面讲到的 DOM 中很重要。)SAX 开发人员只需扩展这个类,然后实现需要插入特定逻辑的方法。所以,SAX 的关键在于为这些不同的回调函数提供代码,然后允许语法分析器在适当的时候触发这些回调函数中的每一个。

因此,典型的 SAX 过程如下:

  • 用特定供应商的语法分析器实现创建一个 SAXParser 实例
  • 注册回调实现(例如,通过使用扩展 HandlerBase 的类)
  • 开始进行语法分析,然后在触发回调实现时等待

JAXP 的 SAX 组件提供执行所有这些步骤的简单方式。如果没有 JAXP,SAX 语法分析器要直接从供应商类(如 org.apache.xerces.parsers.SAXParser )进行实例化,或者必须使用名为 ParserFactory 的帮助类。第一个方法的问题很明显:不独立于供应商。第二个方法的问题在于类厂需要一个自变量,即要使用的语法分析器类的字符串名称(还是那个 Apache 类 org.apache.xerces.parsers.SAXParser )。可以通过将不同语法分析器作为 String 传递来更改语法分析器。使用这种方法不必更改任何 import 语句,但是还是要重新编译类。这显然不是最佳解决方案。如果能够不重新编译类而更改语法分析器,可能会简单得多,是不是这样呢?

JAXP 提供了更好的替代方法:它允许将语法分析器作为 Java 系统属性来提供。当然,当从 Sun 下载版本时,将得到使用 Sun 语法分析器的 JAXP 实现。可以从 Apache XML Web 站点下载在 Apache Xerces 上构建其实现的相同 JAXP 接口。因此(无论哪一种情况),更改正在使用的语法分析器需要更改类路径设置,即从一种语法分析器实现更改到另一个,但是 要求重新编译代码。这就是 JAXP 的魔力,或抽象性。

SAX 语法分析器一瞥

JAXP SAXParserFactory 类是能够轻易更改语法分析器实现的关键所在。必须创建这个类的新实例(等一会将讲到)。创建新实例之后,类厂提供一个方法来获得支持 SAX 的语法分析器。在内部,JAXP 实现处理依赖于供应商的代码,使您的代码不受影响。这个类厂还提供其它一些优秀特性。

除创建 SAX 语法分析器实例的基本工作之外,类厂还允许设置配置选项。这些选项影响所有通过类厂获得的语法分析器实例。JAXP 1.0 中两个可用的功能是设置名称空间敏感性 ( setNamespaceAware (boolean awareness)),和打开确认 ( setValidating (boolean validating))。请记住,一旦设置了这些选项,在调用该方法之后,它们将影响 所有从 类厂获得的实例。

设置了类厂之后,调用 newSAXParser() 将返回一个随时可用的 JAXP SAXParser 类实例。这个类封装了一个下层的 SAX 语法分析器(SAX 类 org.xml.sax.Parser 的实例)。它还防止向语法分析器类添加任何特定于供应商的附加功能。(还记得以前对 XmlDocument 的讨论吗?)这个类可以开始进行实际的语法分析。以下清单显示如何创建、配置和使用 SAX 类厂。



清单 1. 使用 SAXParserFactory
import java.io.File;
            import java.io.IOException;
            import java.io.OutputStreamWriter;
            import java.io.Writer;
            // JAXP
            import javax.xml.parsers.FactoryConfigurationError;
            import javax.xml.parsers.ParserConfigurationException;
            import javax.xml.parsers.SAXParserFactory;
            import javax.xml.parsers.SAXParser;
            // SAX
            import org.xml.sax.AttributeList;
            import org.xml.sax.HandlerBase;
            import org.xml.sax.SAXException;
            public class TestSAXParsing {
            public static void main(String[] args) {
            try {
            if (args.length != 1) {
            System.err.println ("Usage: java TestSAXParsing [filename]");
            System.exit (1);
            }
            // 获得SAX 语法分析器类厂
            SAXParserFactory factory = SAXParserFactory.newInstance();
            //设置设置名称空间敏感性选项,关掉确认选项
            factory.setValidating(true);
            factory.setNamespaceAware(false);
            SAXParser parser = factory.newSAXParser();
            parser.parse(new File(args[0]), new MyHandler());
            } catch (ParserConfigurationException e) {
            System.out.println("The underlying parser does not support " +
            " the requested features.");
            } catch (FactoryConfigurationError e) {
            System.out.println("Error occurred obtaining SAX Parser Factory.");
            } catch (Exception e) {
            e.printStackTrace();
            }
            }
            }
            class MyHandler extends HandlerBase {
            //通过 DocumentHandler, ErrorHandler等实现的SAX回调函数
            }
            

请注意,在这段代码中,在使用类厂时可能发生两个特定于 JAXP 的问题:无法获得或配置 SAX 类厂,以及无法配置 SAX 语法分析器。当无法获得 JAXP 实现中指定的语法分析器或系统属性时,通常会发生第一个问题 FactoryConfigurationError 。当正在使用的语法分析器中的特性不可用时,会发生第二个问题 ParserConfigurationException 。这两个问题都容易处理,应该不会对 JAXP 的使用造成任何困难。

在获得类厂、关闭名称空间并打开“确认”之后,将获得 SAXParser ,然后开始语法分析。请注意, SAX 语法分析器的 parse() 方法取得前面提到的 SAX HandlerBase 类的一个实例。(可以通过完整的 Java 清单 查看该类的实现 。)还要传递要进行语法分析的文件。但是, SAXParser 所包含的远不止这一个方法。
  

使用 SAX 语法分析器

获得 SAXParser 类的实例之后,除了向语法分析器传递 File 进行语法分析之外,还可以用它做更多的事。由于如今大型应用中的应用程序组件之间通信方式,“对象实例创建者就是其使用者”这样的假定并不总是安全的。换句话说,一个组件可能创建 SAXParser 实例,而另一组件(可能由另一开发人员编码)可能需要使用那个实例。由于这个原因,提供了一些方法来确定语法分析器的设置。执行此任务的两个方法是 isValidating() ,它通知调用程序:语法分析器将要、或不要执行“确认”,以及 isNamespaceAware() ,它返回一个指示,说明语法分析器可以或不可以处理 XML 文档中的名称空间。虽然这些方法能提供有关语法分析器可以执行功能的信息,但是无法更改这些特性。必须在语法分析器类厂级别执行该操作。

另外,有多种方法来请求对文档进行语法分析。除了只接受 File 和 SAX HandlerBase 实例,SAXParser 的 parse() 方法还能以 String 形式接受 SAX InputSource 、Java InputStream 或 URL,所有这些都要与 HandlerBase 实例一起提供。所以,不同类型的输入文档可以用不同方式的语法分析来处理。

最后,可以直接通过 SAXParser 的 getParser() 方法获得和使用下层的 SAX 语法分析器( org.xml.sax.Parser 的实例)。获得这个下层实例之后,就可以获得通常的 SAX 方法。下一个清单显示 SAXParser 类(这个 JAXP 中 SAX 语法分析的核心类)的各种使用示例。



清单 2. 使用 JAXP SAXParser
 //获得SAXP的一个实例
            SAXParser saxParser = saxFactory.newSAXParser();
            //查看是否支持 Validate 选项
            boolean isValidating = saxParser.isValidating();
            //查看是否支持 namespace 选项
            boolean isNamespaceAware = saxParser.isNamespaceAware();
            // 运用一个File 和一个SAX HandlerBase 的实例进行多种形式的语法分析
            saxParser.parse(new File(args[0]), myHandlerBaseInstance);
            // 运用一个 SAX InputSource实例 和一个 SAX HandlerBase 实例
            saxParser.parse(mySaxInputSource, myHandlerBaseInstance);
            //运用一个 InputStream 实例和一个SAX HandlerBase 实例
            saxParser.parse(myInputStream, myHandlerBaseInstance);
            // 运用一个 URI 和一个SAX HandlerBase 实例
            saxParser.parse("http://www.newInstance.com/xml/doc.xml", myHandlerBaseInstance);
            //获得底层的(封装)SAX 语法分析器
            org.xml.sax.Parser parser = saxParser.getParser();
            //利用底层的语法分析器
            parser.setContentHandler(myContentHandlerInstance);
            parser.setErrorHandler(myErrorHandlerInstance);
            parser.parse(new org.xml.sax.InputSource(args[0]));
            

目前为止,关于 SAX 已经讲了很多,但是还没有揭示任何不寻常或令人惊奇的东西。事实上,JAXP 的功能很少,特别是当 SAX 也牵涉进来时。这很好,因为有最少的功能性意味着代码可移植性更强,并可以由其他开发人员与任何与 SAX 兼容的 XML 语法分析器一起使用,无论是免费(通过开放源码,希望如此)还是通过商业途径。就是这样。在 JAXP 中使用 SAX 没有更多的东西。如果已经知道 SAX,那么现在已经掌握大约 98% 的内容。只需学习两个新类和两个 Java 异常,您就可以开始了。如果从没使用过 SAX,那也很简单,现在就可以开始。


处理 DOM

如果要休息以迎接 DOM 挑战,那么先别休息。在 JAXP 中使用 DOM 的过程与 SAX 几乎相同,所要做的全部只是更改两个类名和一个返回类型,这样就差不多了。如果理解 SAX 的工作原理和 DOM 是什么,则不会有任何问题。

DOM 和 SAX 的主要差异是它们的 API 结构。SAX 包含一个基于事件的回调函数集,而 DOM 有一个内存中的树状结构。换句话说,在 SAX 中,从不需要操作数据结构(除非开发人员手工创建)。因此,SAX 不提供修改 XML 文档的功能。而 DOM 正好提供这种类型的功能。 org.w3c.dom.Document 类表示 XML 文档,它由表示元素、属性和其它 XML 结构的 DOM 节点 组成。所以,JAXP 无需触发 SAX 回调,它只负责从语法分析返回一个 DOM Document 对象。


DOM 语法分析器类厂一瞥

基本理解 DOM 以及 DOM 和 SAX 的差异之后,就没什么好说的了。以下代码看起来与 SAX 代码类似。首先,获得 DocumentBuilderFactory (与 SAX 中的方式相同)。然后,配置类厂来处理确认和名称空间(与 SAX 中的方式相同)。下一步,从类厂中检索 DocumentBuilder (它与 SAXParser 类似)(与 SAX 中的方式相同. . . 啊,您都知道了)。然后,就可以进行语法分析了,产生的 DOM Document 对象传递给打印 DOM 树的方法。



清单 3. 使用文档构建器类厂
import java.io.File;
            import java.io.IOException;
            import java.io.OutputStreamWriter;
            import java.io.Writer;
            // JAXP
            import javax.xml.parsers.FactoryConfigurationError;
            import javax.xml.parsers.ParserConfigurationException;
            import javax.xml.parsers.DocumentBuilderFactory;
            import javax.xml.parsers.DocumentBuilder;
            // DOM
            import org.w3c.dom.Document;
            import org.w3c.dom.DocumentType;
            import org.w3c.dom.NamedNodeMap;
            import org.w3c.dom.Node;
            import org.w3c.dom.NodeList;
            public class TestDOMParsing {
            public static void main(String[] args) {
            try {
            if (args.length != 1) {
            System.err.println ("Usage: java TestDOMParsing [filename]");
            System.exit (1);
            }
            // 获得 Document Builder Factory
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            //打开确认选项,关掉名称空间敏感性选项。
            factory.setValidating(true);
            factory.setNamespaceAware(false);
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(new File(args[0]));
            // 从DOM 数中打印文档,并加一初始空格
            printNode(doc, "");
            // 在这里也可以对 DOM 文档进行修改
            } catch (ParserConfigurationException e) {
            System.out.println("The underlying parser does not support the requested features.");
            } catch (FactoryConfigurationError e) {
            System.out.println("Error occurred obtaining Document Builder Factory.");
            } catch (Exception e) {
            e.printStackTrace();
            }
            }
            private static void printNode(Node node, String indent) {
            // 打印 DOM 树
            }
            

此代码中可能会出现两个不同的问题(与 JAXP 中的 SAX 类似): FactoryConfigurationErrorParserConfigurationException 。每一个的原因与 SAX 中的相同。不是实现类 ( FactoryConfigurationError ) 中有问题,就是语法分析器不支持请求的特性 ( ParserConfigurationException )。DOM 和 SAX 的唯一差异是:在 DOM 中,用 DocumentBuilderFactory 替代 SAXParserFactory ,用 DocumentBuilder 替代 SAXParser 。就这么简单!(可以 查看完整代码清单 ,该清单包括用于打印 DOM 树的方法。)

使用 DOM 语法分析器

有了 DOM 类厂之后,就可以获得 DocumentBuilder 实例。 DocumentBuilder 实例可以使用的方法与 SAX 的非常类似。主要差异是 parse() 的变种不需要 HandlerBase 类的实例。它们返回表示语法分析之后的 XML 文档的 DOM Document 实例。另一唯一不同之处是:为类似于 SAX 的功能提供了两个方法:用 SAX ErrorHandler 实现来处理语法分析时可能出现的问题的 setErrorHandler() ,和用 SAX EntityResolver 实现来处理实体解析的 setEntityResolver() 。如果不熟悉这些概念,则需要通过联机或在我的书中学习 SAX。以下清单显示使用这些方法的示例。



清单 4. 使用 JAXP DocumentBuilder
    //获得一个 DocumentBuilder 实例
            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            //查看是否支持 Validate 选项
            boolean isValidating = builder.isValidating();
            //查看是否支持 namespace 选项
            boolean isNamespaceAware = builder.isNamespaceAware();
            // 设置一个 SAX ErrorHandler
            builder.setErrorHandler(myErrorHandlerImpl);
            // 设置一个 SAX EntityResolver
            builder.setEntityResolver(myEntityResolverImpl);
            // 运用多种方法对 file 进行语法分析
            Document doc = builder.parse(new File(args[0]));
            // 运用 SAX InputSource
            Document doc = builder.parse(mySaxInputSource);
            // 运用 InputStream
            Document doc = builder.parse(myInputStream, myHandlerBaseInstance);
            // 运用 URI
            Document doc = builder.parse("http://www.newInstance.com/xml/doc.xml");
            

是不是感到 DOM 这一节有些令人厌烦?有这种想法的不止您一个,写 DOM 代码有些令人厌烦是因为它是直接取得所学的 SAX 知识,然后将其用于 DOM。因此,和朋友、同事打赌吧,说使用 JAXP 只是小菜一碟。

更改语法分析器

最后要探讨的主题是 JAXP 轻易更改类厂类使用的语法分析器的能力。更改 JAXP 使用的语法分析器实际意味着更改 类厂,因为所有 SAXParserDocumentBuilder 实例都来自这些类厂。既然确定装入哪个语法分析器的是类厂,因此,必须更改类厂。可以通过设置 Java 系统属性 javax.xml.parsers.SAXParserFactory 来更改要使用的 SAXParserFactory 接口实现。如果没有定义该属性,则返回缺省实现(供应商指定的任何语法分析器)。相同原理适用于 DocumentBuilderFactory 实现。在这种情况下,将查询 javax.xml.parsers.DocumentBuilderFactory 系统属性。就这么简单,我们已经学完了!这就是 SAXP 的全部:提供到 SAX 的挂钩,提供到 DOM 的挂钩,并允许轻易更改语法分析器。

下面是系统寻找xml解析器的顺序
 

随着XML技术的发展,XML解析器也越来越多,比如XercesCrimsonLark等,有些解析器是支持SchemaDTD验证,有些则不支持。

那么,在系统中存在着多个解析器的时候,这时候程序是如何选择解析器的呢?

比如你引用了别人的jar包,很有可能不同的jar包使用了不同的解析器从而引起冲突。

通过阅读JDK源码javax.xml.parsers.FactoryFinderjavax.xml.parsers.SAXParserFactory以及DocumentBuilderFactory发现JDK按照如下顺序:

1. 系统属性javax.xml.parsers.DocumentBuilderFactoryjavax.xml.parsers.SAXParserFactory

2. jdk-dir/lib/jaxp.properties中设定的javax.xml.parsers.DocumentBuilderFactoryjavax.xml.parsers.SAXParserFactory属性

3. 运行时jar包中META-INF/services/javax.xml.parsers.DocumentBuilderFactoryjavax.xml.parsers.SAXParserFactory文件中设定的值

4. 如果上面的解析器都没有找到,则使用Crimson。如果还没有。。。。。。那只能ClassNotFound了。


来寻找XML解析器。

这样,我们可以通过调用System.setProperty(%26#8220;javax.xml.parsers.DocumentBuilderFactory%26#8221;,%26#8221; org.apache.crimson.jaxp.DocumentBuilderFactoryImpl%26#8221;)来设定相应的XML解析器,或者生成jaxp.properties文件,在其中加入如下内容

javax.xml.parsers.DocumentBuilderFactory org.apache.crimson.jaxp.DocumentBuilderFactoryImpl

或者在打jar包的时候加上文件名为javax.xml.parsers.DocumentBuilderFactory的文件,然后再其中写org.apache.crimson.jaxp.DocumentBuilderFactoryImpl


posted @ 2007-04-18 17:09 daniel-shen 阅读(300) 评论(0) 编辑

2007年4月17日

摘要: ZUML是基于XML的。每一个XML元素描述了需要创建的组件。一个XML属性描述了一个要被创建的组件的初始值。一个XML处理指示描述了如何处理整个页面,如页的标题。不同的组件集合通过XML命名空间来区分。例如,XUL的是http://www.zkoss.org/2005/zul,而XHTML是http://www.w3.org/1999/xhtml.XML这一章节提供了和ZK一起工作的XML的最基...阅读全文

posted @ 2007-04-17 14:40 daniel-shen 阅读(318) 评论(0) 编辑

摘要: 事件的监听和处理 本章将描述事件是如何处理的 通过标记语言添加事件监听器 增加监听器最简单的方法是在zuml页面中声明一个属性。监听事件的属性的值是能够被beanshell解释的java代码。 <window title="hello" border="normal"> <button label="say hello" onClick="alert(&quot;hell...阅读全文

posted @ 2007-04-17 14:39 daniel-shen 阅读(717) 评论(0) 编辑

摘要: 4.组件的生命周期本章将讲解页面加载和更新的生命周期页面加载的生命周期 zk需要4个步骤来加载和翻译一张zuml页面:1.页面的初始化2.创建组件 3.事件的处理 4.rendering 下面分别详细的介绍上述4个阶段 页面初始化在这个阶段,zk启动了init函数,如果没有定义这样的处理指示,则跳过。对于每一个init处理指示都有一个class属性,一个指定的类被创建,然后它的doInit方法被调...阅读全文

posted @ 2007-04-17 14:38 daniel-shen 阅读(201) 评论(0) 编辑

摘要: zk体系结构: zk内嵌了体格基于ajax的机制进行自动的交互,一个基于xul的组件丰富可用性,一个标记语言简化开发。 基于ajax的机制包含了三部分。 zk loader,zk au engine和zk client engine.对于用户的请求,zk loader加载zk page,然后转换成html page,发回客户端。一张zk page 是用zuml标记语言写的。zuml,类似与html...阅读全文

posted @ 2007-04-17 14:37 daniel-shen 阅读(695) 评论(0) 编辑

2006年12月22日

摘要: 1.2 - Serviceservice由一个或多个connector组成,一个engine,负责处理所有connector获得的客户请求1.3 - Connectortomcat 的典型connector有两个,一个是在断口8080的侦听浏览器的http请求,一个是在断口8009侦听其他webserver的servlet/jsp代理请求1.4 - Engineengine可以配置多哥虚拟主机vi...阅读全文

posted @ 2006-12-22 09:20 daniel-shen 阅读(118) 评论(0) 编辑