打印本文 打印本文  关闭窗口 关闭窗口
ASP.NET技术FAQ
作者:采集员 文章来源:来源于网络 点击数: 更新时间:2005/9/10 14:20:22
ileMode.Open, FileAccess.Read );
FileStream 继承于 Stream,所以你可以用一个 StreamReader 对象把 FileStream 对象包装起来。这样为一行一行地进行流处理提供了一个良好的界面:

StreamReader sr = new StreamReader( fs );
string curLine;
while( (curLine = sr.ReadLine()) != null )
    Console.WriteLine( curLine );
最后关闭 StreamReader 对象:

sr.Close();
注意这样将自动地在底层 Stream 对象上调用 Close (),所以不必显示地执行 fs.Close()。

 

11.1.2 如何写文本文件?
和读文件的例子相似,只是把 StreamReader 换成 StreamWriter。

 

11.1.3 如何读写二进制文件?
和文本文件类似,只是要用 BinaryReader/Writer 对象而不是 StreamReader/Writer 来包装 FileStream 对象。

 

11.1.4 如何删除文件?
在 System.IO.File 对象上使用静态方法 Delete ():

File.Delete( @"c: est.txt" );
 

11.2 文本处理
11.2.1 是否支持正规表达式?
是的。使用 System.Text.RegularExpressions.Regex 类。例如,以下代码更新 HTML 文件的标题:

FileStream fs = new FileStream( "test.htm", FileMode.Open, FileAccess.Read );
StreamReader sr = new StreamReader( fs );

Regex r = new Regex( "<TITLE>(.*)</TITLE>" );
string s;
while( (s = sr.ReadLine()) != null )
{
    if( r.IsMatch( s ) )
        s = r.Replace( s, "<TITLE>New and improved ${1}</TITLE>" );
    Console.WriteLine( s );
}
 

11.3 Internet
11.3.1 如何下载网页?
首先使用 System.Net.WebRequestFactory 类来获得一个 WebRequest 对象:

WebRequest request = WebRequestFactory.Create( "http://localhost" );
然后请求应答:

WebResponse response = request.GetResponse();
GetResponse 方法被阻塞直到下载完成。然后你能像下面那样访问应答流:

Stream s = response.GetResponseStream();

// Output the downloaded stream to the console
StreamReader sr = new StreamReader( s );
string line;
while( (line = sr.ReadLine()) != null )
    Console.WriteLine( line );
注意 WebRequest 和 WebReponse 对象分别向下兼容 HttpWebRequest 和 HttpWebReponse 对象,它们被用来访问和 http 相关的功能。

 

11.3.2 如何使用代理服务器 (proxy)?
两种?这样做以便影响所有 Web 请求:

System.Net.GlobalProxySelection.Select = new DefaultControlObject( "proxyname", 80 );
另外一种,要想对特定的 Web 请求设置代理服务,这样做:

ProxyData proxyData = new ProxyData();
proxyData.HostName = "proxyname";
proxyData.Port = 80;
proxyData.OverrideSelectProxy = true;

HttpWebRequest request = (HttpWebRequest)WebRequestFactory.Create( "http://localhost" );
request.Proxy = proxyData;
 

11.4 XML
11.4.1 是否支持 DOM?
是的。看看以下示例 XML文档:

<PEOPLE>
    <PERSON>Fred</PERSON>
    <PERSON>Bill</PERSON>   
</PEOPLE>   
可以这样处理此文档:

XmlDocument doc = new XmlDocument();
doc.Load( "test.xml" );

XmlNode root = doc.DocumentElement;

foreach( XmlNode personElement in root.ChildNodes )
    Console.WriteLine( personElement.FirstChild.Value.ToString() );
输出为:

Fred
Bill
 

11.4.2 是否支持 SAX?
不。作为替换,提供了一个新的 XmlReader/XmlWriter API。像 SAX 一样,它是基于流的,但它使用“pull”模型而不是 SAX 的“push”模型。这是一个例子:

XmlTextReader reader = new XmlTextReader( "test.xml" );

while( reader.Read() )
{
    if( reader.NodeType == XmlNodeType.Element && reader.Name == "PERSON" )
    {
        reader.Read(); // Skip to the child text
        Console.WriteLine( reader.Value );
    }
}
 

11.4.3 是否支持 XPath?
是的,通过 XmlNavigator 类 (DocumentNavigator 是从 XmlNavigator 导出的):

XmlDocument doc = new XmlDocument();
doc.Load( "test.xml" );

DocumentNavigator nav = new DocumentNavigator(doc);
nav.MoveToDocument();

nav.Select( "descendant::PEOPLE/PERSON" );

while( nav.MoveToNextSelected() )
{
    nav.MoveToFirstChild();
    Console.WriteLine( "{0}", nav.Value );
}
 

11.5 线程
11.5.1 是否支持多线程?
是的,对多线程有广泛的支持。系统能产生新线程,并提供应用程序可以使用的线程池。

 

11.5.2 如何产生一个线程?
创建 System.Threading.Thread 对象的一个实例,把将要在新线程中执行的 ThreadStart 示例传递给它。例如:

class MyThread
{
    public MyThread( string initData )
    {
        m_data = initData;
        m_thread = new Thread( new ThreadStart(ThreadMain) );
        m_thread.Start();
    }

    // ThreadMain() is executed on the new thread.
    private void ThreadMain()
    {
        Console.WriteLine( m_data );
    }

    public void WaitUntilFinished()
    {
        m_thread.Join();
    }

    private Thread m_thread;
    private string m_data;
}
这里创建 MyThread 的一个实例就足以产生线程并执行 MyThread.ThreadMain () 方法:

MyThread t = new MyThread( "Hello, world." );
t.WaitUntilFinished();
 

11.5.3 如何停止一个线程?
有好几个办法。首先,你能使用自己的通讯机制告诉 ThreadStart 方法结束。另外 Thread 类有内置的支持来命令线程停止。基本的两个方法是 Thread.Interrupt () 和 Thread.Abort ()。前者导致抛出一个 ThreadInterruptedException 并随后进入 WaitJoinSleep 状态。换句话说,Thread.Interrupt 是一种礼貌的方式,它请求线程在不再进行任何有用的工作时自行停止的。与此相对应,Thread.Abort () 抛出一个 ThreadAbortException 而不管线程正在做什么。而且,ThreadAbortException 不能像通常的异常那样被捕获 (即使最终将执行 ThreadStart 的终止方法)。Thread.Abort () 是一般情况下不需要的非常手段。

 

11.5.4 怎样使用线程池?
通过向 ThreadPool.QueueUserWorkItem () 方法传递 WaitCallback 的一个实例:

class CApp
{
    static void Main()
    {
        string s = "Hello, World";
        ThreadPool.QueueUserWorkItem( new WaitCallback( DoWork ), s );

        Thread.Sleep( 1000 );    // Give time for work item to be executed
    }

    // DoWork is executed on a thread from the thread pool.
    static void DoWork( object state )
    {
        Console.WriteLine( state );
    }
}
 

11.5.5 怎样知道我的线程池工作项目是在何时完成的?
没有方法询问线程池这类信息。你必须在 WaitCallback 方法中放置代码来发出信号以表明它已经完成。这里事件也很有用处。

 

11.5.6 怎样防止对数据的并发访问?
每个对象有一个与之相联的并发锁 (受批评的部分)。System.Threading.Monitor.Enter/Exit 方法用来获得和释放锁。例如,下面类的实例只允许一个线程同时进入方法 f ():

class C
{
    public void f()
    {
        try
        {
            Monitor.Enter(this);
            ...
        }
        finally
        {
            Monitor.Exit(this);
        }
    }
}
C# 有一个关键字‘lock’提供了以上代码的简单形式:

class C
{
    public void f()
    {
        lock(this)
        {
            ...
        }
    }
}
注意,调用 Monitor.Enter (myObject) 并不意味着对 myObject 的所有访问都被串行化了。它意味着请求同 myObject 相联的同步锁,并且在调用 Monitor.Exit(o) 之前,没有任何其它线程可以请求该锁。换句话说,下面的类和以上给出的类在功能上是等同的:

class C
{
    public void f()
    {
        lock( m_object )
        {
            ...
        }
    }

    private m_object = new object();
}
 

11.6 跟踪
11.6.1 有内置的跟踪/日志支持吗?
是的,在 System.Diagnostics 命名空间中。有两个处理跟踪的主要的类?Debug 和 Trace。它们以相似的方式工作?不同之处是 Debug 类中的跟踪只能在用 DEBUG 标志生成的代码中工作,而 Trace 类中的跟踪只能在指明了 TRACE 标记生成的代码中工作。典型地,这意味着你应该在你希望能在 debug 和 release 版本中都能跟踪时使用 System.Diagnostics.Trace.WriteLine,而在你希望只能在 debug 版本中能跟踪时使用 System.Diagnostics.Debug.WriteLine。

 

11.6.2 能否将跟踪输出重定向到一个文件?
是的。Debug 类和 Trace 类都有一个 Listeners 属性,它们分别收集你用 Debug.WriteLine 或 Trace.WriteLine 产生的输出。默认情况下 Listeners 只有一个收集槽,它是 DefaultTraceListener 类的一个实例。它将输出发送到 Win32 的 OutputDebugString () 函数和 System.Diagnostics.Debugger.Log () 方法。调试时这很有用,但如果你试图从客户站点跟踪一个问题,将输出重定向到一个文件中就更为恰当。幸运的是,为此目的提供了 TextWriterTraceListener 类。

这里是 TextWriterTraceListener 如何将 Trace 输出重定向到一个文件:

Trace.Listeners.Clear();
FileStream fs = new FileStream( @"c:log.txt", FileMode.Create, FileAccess.Write );
Trace.Listeners.Add( new TextWriterTraceListener( fs ) );

Trace.WriteLine( @"This will be writen to c:log.txt!" );
注意使用 Trace.Listeners.Clear () 去掉了默认的 listener。如果不这样做,输出将在文件和 OutputDebugString () 中同时产生。一般情况下你不希望如此,因为 OutputDebugString () 导致很大的性能开销。

 

11.6.3 能否定制跟踪的输出?
是的。你能编写你自己的 TraceListener 导出类,并把所有的输出重定向到它上面。这里有一个简单的例子,它从 TextWriterTraceListener 导出 (并随后内建了对写文件的支持) 并在每个输出行上添加时间信息和线程 ID:

class MyListener : TextWriterTraceListener
{
    public MyListener( Stream s ) : base(s)
    {
    }

    public override void WriteLine( string s )
    {
        Writer.WriteLine( "{0:D8} [{1:D4}] {2}",
            Environment.TickCount - m_startTickCount,
   

上一页  [1] [2] [3] [4] [5]  下一页



打印本文 打印本文  关闭窗口 关闭窗口