Wednesday, November 28, 2007

(ZT)为什么要升级到SQL Server 2005

 

2007-11-01 09:00 作者: pottermiss 出处: 论坛整理 责任编辑:幽灵

  很多人关心的和担心的都是 SQL Server 2005 相对它的前版本SQL Server 2000所做的重大改进或新增功能。在我升级到SQL2005之后,不得不说的:你也值得拥有。(套用一句广告语,呵呵)

  我总结了一下个人认为SQL Server 2005 中最值得你为之升级的10 个理由。无论你是想了解或学习SQL Server 2005,还是正在评估或考虑升级到SQL Server 2005,我相信当时你看完这篇帖子一定会对你的决定起到参考作用。

升级理由一:数据分区

  只有到了2005 版本SQL Server才拥有了真正的表和索引数据分区技术。这个技术一下子使SQL Server数据库从“青壮年”成长为成熟的企业级数据库产品,是一个里程碑性质的标志。数据分区技术极大加强了表的可伸缩性和可管理性,使得SQLServer 处理海量数据的能力有了质的飞跃,是我认为最值得升级的一个理由。

升级理由二:可编程性

  CLR 集成

  SQL Server 2005的可编程性是值得升级的第二个重要理由。从来没有哪一个版本能像SQL Server 2005 这样带来这么多编程方面的变革。说老实话,在我知道的瞬间我是惊呆了。有些变化是革命性的。如CLR(Common Language Runtime,公共语言运行时)集成。你可以轻松利用.NET语言的优势如其面向对象的封装、继承和多态特性,编写出那些需要对数据进行复杂数值计算或逻辑的代码,如字符串处理,数据加密算法,XML数据操作等等。你现在需要的仅仅是考虑什么时候使用T-SQL 语言,什么时候使用CLR。我猜测那些SQL Server软件开发商几乎会立即升级到SQLServer 2005 享受数据库编程的便捷。

  T-SQL 语言增强

  SQL Server 2005 中的T-SQL语言有了非常大的改进。其中笔者最为称道的是现在可以使用和C++或C#类似的TRYCATCH结构对T-SQL 进行错误处理了,大大简化了T-SQL错误处理编程。估计很多T-SQL语言使用者可能就为了这个TRY-CATCH 结构而迫不及待地升级到SQL Server 2005。

升级理由三:安全

  SQL Server 2005 的安全功能是我认为值得升级的第三个理由。SQL Server 2005 的安全达到了前所未有的强大水平,有着比以前版本更清晰的安全模型即主体,安全对象和权限。

  如果你需要保护数据库中的敏感数据,那么SQL Server2005 中的数据加密功能绝对值得考虑。以前不止一次有客户问我如何加密数据库中的某些数据,是否可以使用一些内部不公开的函数如PWDENCRYPT加密数据。我的回答是使用Windows的EFS(加密文件系统)功能加密数据库文件或在应用程序层对数据加密后再存储。现在用户期盼已久的数据加密功能终于在SQL Server 2005 中得到实现,那些有机密数据需要保护的用户值得高兴了。SQL Server 2005不是简单的提供一些加密函数,而是把市场上已经成熟的数据安全技术引进到数据库中,有一个清晰的加密层次结构。SQL Server 2005 支持证书(certificate),非对称密钥和对称密钥算法,一是防止敏感数据被泄漏,二是防止数据被篡改。对称密钥支持RC4,RC2,TripleDES 和AES算法,而非对称密钥使用RSA 算法。证书其实就是非对称密钥中公钥的容器。密钥管理是安全中比较弱的部分。SQL Server 2005 每一层都使用证书、非对称密钥和对称密钥的组合对它下面的一层进行加密,提高了密钥安全性。出于性能考虑,一般不用加密强度大的非对称密钥或证书直接加密数据,而是使用对称密钥加密数据获得较快的性能,然后使用证书或非对称密钥加密对称密钥。

升级理由四:快照隔离

  你还在为系统出现的阻塞(blocking)或死锁(deadlock)现象苦恼吗?快试试SQL Server 2005 中的快照隔离吧。通过行版本(row versioning)控制技术,SQL Server 2005 除了原来支持的四种事务隔离级别(脏读、提交读、可重复读、可串行读)外新增了一个快照(SNAPSHOT)隔离级别,有可能使阻塞或死锁成为历史。SQL Server在TEMPDB中存放不同版本的数据行,select 语句读取这些不同版本的行,读操作不阻塞写数据,写操作也不阻塞读操作,这样那些由于读/ 写争用导致的大量死锁的系统将从中获得无穷益处。如果你的系统复杂难优化,那么升级到SQL Server 2005 试试快照隔离级别,也许会有意想不到的效果。

  SQL Server 2005中的快照隔离可细分为两种即READ_COMMITTED_SNAPSHOT和ALLOW_SNAPSHOT_ISOLATION。建议大家多使用前者,因为已提交读隔离可用于大多数现有应用程序,而不需要进行任何更改,其占用的TEMPDB空间也少。可以预见如果使用快照隔离级别,那么需要特别关注TEMPDB的大小和性能。你也许需要把TEMPDB放在有足够空间的单独磁盘上以提高性能。

  考虑到快照隔离在避免阻塞和死锁方面的作用,我把它作为升级的第四个理由。

升级理由五:数据库镜像

  对于那些要求高可用性的用户来说,数据库镜像也许是考虑升级的唯一理由。SQL Server 2005的前版本在高可用性方面提供了故障转移群集(Failover Cluster)和Log shipping方案。群集方案的一个好处是在一台机器发生问题时它可以提供极快的故障转移能力,在备份服务器上联机数据库,应用程序只需重新连接即可。群集方案的一个缺点是数据库放在共享盘上,有单点失效这个缺点,一旦共享盘失败将导致整个系统崩溃。所以群集方案一般都要结合严紧的备份方案一起使用。而logshipping系统有一个时间上的延迟,且如果日志备份很大,传送速度也是个问题。SQL Server 2005引入的数据库镜像可作为故障转移群集或Log shipping 的替代或补充方案来提高数据库的高可用性。镜像的主要优点是它比前两者更容易管理,没有群集的单点失效缺点,也没有log shipping 的时间延迟。镜像服务器可以放在很远的地方,提高了作为备份服务器的高可用性。

升级理由六:商务智能BI 增强

  SQL Server 2005 对已经有或打算开发基于SQL Server 的商务智能方案的用户吸引力极大。SQL Server 2005中有关商务智能方面的增强很多,是升级的很好理由。首先是传统的DTS(Data Transformation Services)被新的IS(Integration Services)代替。SQL Server 2000 中的DTS用来在不同服务器之间转移数据,但对于复杂重复的工作流DTS倍感吃力。IS重新改写了DTS的数据流引擎,引入提取、转换和加载(ETL)数据的新编程体系,将数据流与控制流分开,开发能力大大加强,包部署、管理和性能方面也比DTS上了一个数量级。笔者看来,DTS终于从原来的小打小闹成长为成熟的IS 数据集成服务体系。

  分析服务(Analysis Services)在SQL Server 2005 中也有很多改进。原来没有profiler想跟踪分析服务里面的语句非常痛苦。现在2005 终于支持profiler了。Profiler对性能调优和排查错误将非常有用。分析服务2005 真正具备了实时分析能力,新增加了四种数据挖掘算法,也支持.NET语言进行开发(如存储过程等)。至于报表服务,2005 版本中添加了报表生成器和模型设计器这两个新工具,支持报表拖拉设计。2005 的报表改进如新的打印功能、多值参数等。设计过报表的人员会深深知道多值参数的妙处。

  另外,无论是IS、报表服务等都可以在类似Visual Studio的环境中开发,任务完成不过鼠标拖拉之间,非常容易上手。

升级理由七:全文搜索增强

  相对前版本SQL Server 2005中性能提升最多的部分当数全文检索。SQL Server 2000 中的全文本检索和SQL Server 7.0中的差别不大,处于能用的水平。在SQL Server 2000中使用全文检索一个最大的痛苦是建立全文索引的性能不好,需要的时间太长,特别是在表很大的情况下。一个几千万行数据的表也许需要数个小时到数天时间才能完成全文索引的建立。SQL Server 2005全文检索在开发的时候就集中于三点:性能,集成,和可扩展性。据开发小组人员的简单测试,原来在SQL Server 2000中建立全文索引需要14天的表,现在只需要几个小时!几乎有上百倍的性能提升,只能用“惊异”来形容。其相关的全文检索语句也有30%~50%甚至更高的性能提高。性能方面的提高得益于全新设计的全文检索引擎。其中关键的一点设计是全文检索引擎现在使用共享内存和SQL Server 进行数据大规模并发交互,而不是原来基于逐行的方式,使得性能上了好几个数量级。

  除了性能,SQL Server 2005 中的全文索引的集成性也大大加强。在SQL Server 2000 中很难对全文检索进行备份。一旦有数据库恢复或移动,你得重新重建索引。对于几百个GB的数据库,重建索引几乎是不能接受的恶梦。现在终于可以和数据库一起备份和恢复全文索引了。你不再需要在恢复数据库后重建全文索引了!恶梦终于成为历史。除了可以备份外,你也可以方便的改变全文索引的磁盘位置。你甚至可以在一个热备机器上把全文索引建立好,然后copy 这个索引到生产服务器上使用。

升级理由八:可用性功能增强

  索引联机操作。除了数据库镜像,SQL Server 2005 中可用性还有很多其他提高。索引现在可以使用ONLINE关键字进行在线建立或重建或删除了。它的技术要点是在内存里面动态生成索引的另一个副本从而不影响原来查询的进行。一旦索引副本完成操作即替代原来索引成为当前索引。我认为索引联机操作的意义是很大的,因为很多数据库系统都有定期调整或维护索引方面的需求。有了2005 你无需担心业务的正常运行而大胆的对索引进行维护或修改。

  页校验和。SQL Server 2005中的数据库页引入校验和增强了数据的可靠性。除了原来SQL Server 2000 中已有的TORN_PAGE_DETECTION 外,SQL Server 2005 新增实现了页的检验和(CHECKSUM)。你使用ALTER DATABASE语句的SET PAGE_VERIFY子句即可指定。它的原理是向磁盘中写入8K数据页面时,SQL Server计算整个8K页面内容的校验和并将该值存储在页头中。再次从磁盘中读取页时,SQL Server动态计算读取到的页面内容的校验和,并与存储在页头中的校验和值进行比较。如果不相等则意味着页面有物理损坏,需要检查IO硬件。另外设置检验和的另一个好处是还可以在备份和还原操作过程中使用RESTORE VERIFYONLY语句验证每一数据页的完整性从而确认备份文件没有物理损坏。

  在线还原。在数据库的某一部分未恢复前,用户无法对该部分进行访问,但可以访问所有其他数据。SQL Server 2000中如果数据库在还原或recovery当中,用户不能访问数据库。这样如果数据库很大需要rollback或rollforward的事务很多的话,recovery的时间会出奇的长。SQL Server 2005 的在线还原功能使得数据库在很短的时间内变得可用。

升级理由九:复制增强

  SQL Server 2000 中的复制功能已经很好。我这里把复制作为升级的一个理由因为SQL Server 2005在原来的基础上又增添了不少的功能。如peer-to-peer对等复制,可以在参与者之间相互进行复制,这样你可以采用对等复制在复制参与者之间建立某种程度的负载平衡。合并复制现在支持通过HTTPS进行数据同步,可以方便建立基于INTERNET 的复制。发布表现在可以使用标准的T-SQL语句如Alter Table等进行结构修改然后被复制而不是仅仅局限于使用sp_repladdcolumn和sp_repldropcolumn存储过程。在SQL Server 2000 中,仅支持向其他数据库(如DB2或Oracle)发布数据,而在SQL Server 2005 中,可将Oracle 数据库直接复制到SQL Server。可以从备份中初始化事务性订阅而不是仅仅局限于从快照对复制进行初始化,等等……

升级理由十:异步处理能力

  SQL Server 2005 通过引入全新的Service Broker 提供了革命性的异步处理能力。Service Broker提供了一个功能强大的异步编程模型。它为数据库应用程序增加了可靠、可扩展、分布式异步功能异步编程,允许程序仅仅在资源可用时才去执行占用大量资源的任务,以此来缩短响应时间,提高吞吐量。在我看来,Broker的最大好处一是异步执行能力,提高了可伸缩性,二是可靠执行,三是集成于数据库中,备份数据库就备份了broker 的消息队列。SQL Server 2005 中的查询通知就是基于Service Broker的应用。你可以使用查询通知功能来发送一个命令到SQL Server请求在查询结果发生变化时接收SQL Server的通知。这样就可以只有在程序以前检索的结果发生变化时,才需要重新查询数据库。一个可以预见的应用是在使用缓存的Web 站点中。Web站点首先发送语句到数据库服务器,获得数据,缓存到本地,然后只有在收到查询通知的时候才清理缓存,重新查询数据。这个机制避免了重复轮询SQL Server,大大减轻了服务器的负载,也提高了Web 站点的伸缩性。

  因为SQL Server 2005 的Service Broker带来了数据库编程异步处理能力的革命,我把它作为升级的第十个理由。

Sunday, November 25, 2007

Using a Subquery in a T-SQL Statement (ZT)

 

Sometimes the criteria for determining which set of records will be affected by a SELECT, UPDATE, DELETE and/or INSERT statement cannot be obtained by hard coding the selection criteria. Occasionally there is a need to use the results of a SELECT statement to help determine which records are returned or are affected by a T-SQL statement. When a SELECT statement is used inside another statement, the inside SELECT statement is known as a subquery. Subqueries can help to dynamically control the records affected by an UPDATE, DELETE or INSERT statement, as well as to help determine the records that will be returned by a SELECT statement. This article will show different examples of how to use a subquery to help clarify the records affected or selected by a T-SQL statement.

What is a Subquery?

A subquery is a SELECT statement that is nested within another T-SQL statement. A subquery SELECT statement if executed independently of the T-SQL statement, in which it is nested, will return a result set. Meaning a subquery SELECT statement can standalone and is not depended on the statement in which it is nested. A subquery SELECT statement can return any number of values, and can be found in, the column list of a SELECT statement, a FROM, GROUP BY, HAVING, and/or ORDER BY clauses of a T-SQL statement. A Subquery can also be used as a parameter to a function call. Basically a subquery can be used anywhere an expression can be used.

Use of a Subquery in the Column List of a SELECT Statement

Suppose you would like to see the last OrderID and the OrderDate for the last order that was shipped to Paris. Along with that information, say you would also like to see the OrderDate for the last order shipped regardless of the ShipCity. In addition to this, you would also like to calculate the difference in days between the two different OrderDates. Here is my T-SQL SELECT statement to accomplish this:

select top 1 OrderId,convert(char(10),
OrderDate,121) Last_Paris_Order,
(select convert(char(10),max(OrderDate),121) from
Northwind.dbo.Orders) Last_OrderDate,
datediff(dd,OrderDate,
(select Max(OrderDate)from Northwind.dbo.Orders)) Day_Diff
from Northwind.dbo.Orders
where ShipCity = 'Paris'
order by OrderDate desc

The above code contains two subqueries. The first subquery gets the OrderDate for the last order shipped regardless of ShipCity, and the second subquery calculates the number of days between the two different OrderDates. Here I used the first subquery to return a column value in the final result set. The second subquery was used as a parameter in a function call. This subquery passed the "max(OrderDate)" date to the DATEDIFF function.

Use of a Subquery in the WHERE clause

A subquery can be used to control the records returned from a SELECT by controlling which records pass the conditions of a WHERE clause. In this case the results of the subquery would be used on one side of a WHERE clause condition. Here is an example:

select distinct country from Northwind.dbo.Customers 
where country not in (select distinct country from Northwind.dbo.Suppliers)

Here I have returned a list of countries where customers live, but there is no supplier located in that country. I suppose if you where trying to provide better delivery time to customers, then you might target these countries to look for additional suppliers.

Suppose a company would like to do some targeted marketing. This targeted marketing would contact customers in the country with the fewest number of orders. It is hoped that this targeted marketing will increase the overall sales in the targeted country. Here is an example that uses a subquery to return the customer contact information for the country with the fewest number of orders:

select Country,CompanyName, ContactName, ContactTitle, Phone
from Northwind.dbo.Customers
where country =
(select top 1 country
from Northwind.dbo.Customers C
join
Northwind.dbo.Orders O
on C.CustomerId = O.CustomerID
group by country
order by count(*))

Here I have written a subquery that joins the Customer and Orders Tables to determine the total number of orders for each country. The subquery uses the "TOP 1" clause to return the country with the fewest number of orders. The country with the fewest number of orders is then used in the WHERE clause to determine which Customer Information will be displayed.

Use of a Subquery in the FROM clause

The FROM clause normally identifies the tables used in the T-SQL statement. You can think of each of the tables identified in the FROM clause as a set of records. Well, a subquery is just a set of records, and therefore can be used in the FROM clause just like a table. Here is an example where a subquery is used in the FROM clause of a SELECT statement:

select au_lname, au_fname, title from 
(select au_lname, au_fname, au_id from pubs.dbo.authors
where state = 'CA') as a
join
pubs.dbo.titleauthor ta on a.au_id=ta.au_id
join
pubs.dbo.titles t on ta.title_id = t.title_id

Here I have used a subquery to select only the author record information, if the author's record has a state column equal to "CA." I have named the set returned from this subquery with a table alias of "a." I can then use this alias elsewhere in the T-SQL statement to refer to the columns from the subquery by prefixing them with an "a", as I did in the "ON" clause of the "JOIN" criteria. Sometimes using a subquery in the FROM clause reduces the size of the set that needs to be joined. Reducing the number of records that have to be joined enhances the performance of joining rows, and therefore speeds up the overall execution of a query.

Here is an example where I used a subquery in the FROM clause of an UPDATE statement:

set nocount on 
create table x(i int identity,
a char(1))
insert into x values ('a')
insert into x values ('b')
insert into x values ('c')
insert into x values ('d')
select * from x

update x
set a = b.a
from (select max(a) as a from x) b
where i > 2

select * from x
drop table x

Here I created a table named "x," that has four rows. Then I proceeded to update the rows where "i" was greater than 2 with the max value in column "a". I used a subquery in the FROM clause of the UPDATE statement to identity the max value of column "a."

Use of a Subquery in the HAVING clause

In the following example, I used a subquery to find the number of books a publisher has published where the publisher is not located in the state of California. To accomplish this I used a subquery in a HAVING clause. Here is my code:

select pub_name, count(*) bookcnt 
from pubs.dbo.titles t
join
pubs.dbo.publishers p
on t.pub_id = p.pub_id
group by pub_name
having p.pub_name in
(select pub_name from pubs.dbo.publishers where state <> 'CA')

Here my subquery returns the pub_name values for all publishers that have a state value not equal to "CA." The HAVING condition then checks to see if the pub_name is in the set returned by my subquery.

Conclusion

The subquery is a valuable concept to understand. Creative use of a subquery allows the desired results to be returned in a single T-SQL statement, and helps avoid the use of temporary tables and cursors to solve complicated selection criteria. In addition, depending on the query, a subquery might improve performance by reducing the number of records that SQL Server needs to process. In my next article, I will expand on the idea of subqueries by looking at correlated subqueries.

Thursday, November 08, 2007

Desing Pattern

 

  • Creational
    • Facotory Method
    • Abstract Factory
      • When we need to create a object which can be decided in the subclass , usually we will use Facotry Method.(Inhertiance will be used)
      • When we want to create mutiple objects which are related and the system only need one of them, usually we will use Abstract Factory.(Composition will be used)
      • Abstract Factory需要处理的是“一系列相互依赖”的产品的创建,即抽象工厂创建的是一组产品;而Factory Method需要处理的单个产品的创建工作。
        当一个类不知道他所必需创建对象的类或一个类希望有子类指定他所创建的类型时(也就是说一个类中的某个对象需要由子类来创建时),此时我们使用Factory Method
        当系统有多于一个的产品组合,而系统只需要使用其中某一产品组合,此时我们一般使用Abstract Factory
      • 分析了上面的优缺点,当我们在遇到如下情况时,应当考虑使用抽象工厂模式:
        1、一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的;
        2、这个系统有多于一个的产品组合,而系统只需要使用其中某一产品组合;
        3、同属于同一个产品组合的产品是在一起使用的,这一约束必须在系统的设计中体现出来;
        4、系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现;
  • Structure : to compose bigger structure
    • Decorator
  • Behaviour : Distribute the  algorithim and responsibility between different objects .
    • Stragtegy

 

 

Adapter   VS   Decorator VS Facade

 Adapter: Class adapter(using mutiple inheritance); Object adapter(Composition)

  • They are all wrappers using composition(Adapter ,object adapter)
  • Adapter wraps an object to change its interface
  • Decorator wraps an object to add new behaviours and responsibilites dynamically 
  • Facadie wraps a collection of objects to simplify and get a uniformed handling method.

Bridge    VS   Stragtegy VS State

 

Strategy:是一个锥把可以使用多个锥头;
Bridge:是不同锥把可以使用多个锥头;
当Bridge的左边只有一个时就退化为Strategy了!
____________________
这才说到点上了。不只是context 不一样,表现就是不一样的!

 

Composite VS Decorator VS Proxy

 

 Decorator VS Proction Proxy: The selection is depends on the intent.

for Proction Proxy , the structure is same as Decorator.

  • A Protection Proxy protects an object
  • Decorator adds behaviour to an object

 

Decorator VS Stragtegy : They all can add behavior to an object. The selection is depends on the intent.

  • Decorator focus on adding behaviors dynamically
    • Can be used for adding behaviors for an instance of object (not an object) which mens the object code or structure can not be changed
    • Can not be shared by other instance of object
    • The instantiation must be transparent which means
      • (right)object o= new Decorator(new object() ) ,
      • (wrong) Decortor o= new Decorator()
  • Stragtegy
    • The object will always have the stragtegy object
    • Can be shared by other object

 Template && Factory

  • Factory can be used without Template
  • Template usually call Factory Methods
  • Template just like "Pull Up Method To Super Class"

Decorator VS Proxy

  • They all have a pointer with other object
  • Decorator is using the object to add new behavior
  • Proxy is using the object to do the real work
    • when it is difficult to access the object , using proxy to access. 

Adapter VS Proxy

  • They all use composition to have another object  and forward request to it.
  • Adapter changes the interface of object
  • Proxy implement the same interface


Builder VS Composite VS Collectiing Parameter

  • In Composite , can use builder pattern to create the tree(Encapsulate Composite with builder)
  • In Composite, can aslo use collecting parameter to Move Accumulation to Collecting Parameter
  • For using builder in Compoiste, will build mutiple objects like Nodes (Nodesbuilder.build(parent);
  • For using collecting parameter in Composite, will build single object like a xml string(stringbuilder.add(starttag))

 

Vistor:

  • add new feature for a composition of objects but not want to add it to each one in the composition. For example , have three objects :Clerk, Boss, Directory(they have a common interface :Employee). Now we want to add addincome feature for these three classes. But we don't want to add addincome function in each of these three.
  • So we can use Vistor pattern.
    • Create a AddIncomeVistor class.
      • AddIncome(Employee)
    • In these three class , write a Accept(AddIncomeVistor) method: AddincomeVisotr.AddIncome(this);
  • Now we can call Element.accept(AddIncomeVistor) to add this new feature  without making changes in three objects.
  • Vistor pattern break "Encapsulation" and use "Double-Dispatch".
  • 访问者模式有如下的优点:

    1. 访问者模式使得增加新的操作变得很容易。如果一些操作依赖于一个复杂的结构对象的话,那么一般而言,增加新的操作会很复杂。而使用访问者模式,增加新的操作就意味着增加一个新的访问者类(Vistor),因此,变得很容易。
    2. 访问者模式将有关的行为集中到一个访问者对象中,而不是分散到一个个的节点类中。
    3. 访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。迭代子只能访问属于同一个类型等级结构的成员对象,而不能访问属于不同等级结构的对象。访问者模式可以做到这一点。
    4. 积累状态。每一个单独的访问者对象都集中了相关的行为,从而也就可以在访问的过程中将执行操作的状态积累在自己内部,而不是分散到很多的节点对象中。这是有益于系统维护的优点。

    访问者模式有如下的缺点:

    1. 增加新的节点类变得很困难。每增加一个新的节点都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中增加相应的具体操作。
    2. 破坏封装。访问者模式要求访问者对象访问并调用每一个节点对象的操作,这隐含了一个对所有节点对象的要求:它们必须暴露一些自己的操作和内部状态。不然,访问者的访问就变得没有意义。由于访问者对象自己会积累访问操作所需的状态,从而使这些状态不再存储在节点对象中,这也是破坏封装的。

Tuesday, November 06, 2007

Get All Files Under A Directory(Recursive)

 // deep traversal

 

Public void GetAllFiles(string directorypath)

{

 // get sub dirs

string[] Dirs = System.IO.Directory.GetDirectories(directorypath);

if (Dirs.Count>0)

{// have subdirectory 

   foreach (string dir in Dirs)
  {
         GetAllFiles(dir); // recursive calling
  }

}

// handle file in folder

// get all files

System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(directorypath);

foreach (System.IO.FileInfo fi in di)

{

   // handle each file

}

 

 

}