zoukankan      html  css  js  c++  java
  • 【.net 深呼吸】写入日志文件

    记录日志,一方面可以把日志写入系统的日志存储中,可在“事件查看器”窗口中查看;如果不喜欢写到系统的日志文件中,也可以写到自己定义的文件中。

    其实,日志文件就是文本文件,可能有朋友会想到用写入文本文件的方式来写日志。当然,这样做也是可以的,不过,.NET 类型库提供了两个专用记录信息的类。

    Debug 类大家都很熟悉,就是可以在VS的“输出”窗口写入调试信息,另外,有一个跟Debug很像的类——Trace。Debug通常只会在调试版本中使用,Trace既可以在调试版本中用,也可以用于发布(Release)版本。

    下面以Write方法为例,看看Debug类和Trace类的定义有什么不同。

    // Debug
    [ConditionalAttribute("DEBUG")]
    public static void Write( Object value )
    
    // Trace
    [ConditionalAttribute("TRACE")]
    public static void Write( Object value )

    ConditionalAttribute用于指定一个条件,当条件中给出的条件编译符号存在时才会执行。DEBUG和TRACE这两个符号可以在编译的时候指定,也可以在VS项目属性中指定。

    接下来我们了解一下监听器,它的公共基类是TraceListener,而Debug和Trace类都有一个Listeners集合,可以添加从TraceListener派生的任意实例。即使我们没有在代码中向Listeners集合添加元素,在应用程序运行时,它会自动添加一个默认的监听器,类型为DefaultTraceListener。

    好了,前面都是F话,只是给大家娱乐的,说到了DefaultTraceListener,就进入本文主题了,看一下,这个类是不是有个属性叫LogFileName?这就对了,只要把日志文件的相对路径或绝对路径赋给它就行了,日志文件可以不存在,但目录应该是存在的。

    来来来,咱们来练习一下。

                // 从 Listeners 集合中找出默认监听器
                DefaultTraceListener listener = Trace.Listeners["Default"] as DefaultTraceListener;
    
                // 指定日志文件
                if (listener != null)
                {
                    listener.LogFileName = "MyApp.log";
                }
    
                // 测试写入
                Trace.WriteLine("今天天气很好。");
                Trace.WriteLine("明天天气依旧地热。");
                Trace.WriteLine(DateTime.Today.ToLongDateString());

    刚刚说过,默认情况下,Listeners集合中会有一个DefaultListener监听器,而且它的Name属性为“Default”,因此,我们按照名称就可以把它取出来,然后设置它的LogFileName属性,这里我用的是相对路径,即创建的日志文件位于可执行文件相同的目录下。

    使用Trace类而不用Debug类,是因为Trace可以在调试版本中用,也可以在发布版本中用。从运行过程来看,跟踪信息既会出现在“输出”窗口中,也会同时写入前面指定的日志文件中。

    待上面示例运行后,再到程序目录下,用记事本打开日志文件,就能看到记录的信息了。

    要是你比较不喜欢用默认的监听器,还可以先把Listeners集合清空,然后Add一个别的监听器,除了DefaultTraceListener,还有TextWriterTraceListener、XmlWriterTraceListener等,它们的继承关系就不说了,自己看文档。

    下面我们来用TextWriterTraceListener来写入日志文件。

            static void Main(string[] args)
            {
                // 清空监听器集合
                Trace.Listeners.Clear();
                // 加入新的监听器
                TextWriterTraceListener listener = new TextWriterTraceListener("app.log");
                Trace.Listeners.Add(listener);
    
                // 测试写入信息
                Trace.WriteLine("a - b - c");
                Trace.WriteLine(DateTime.Now.ToLongTimeString());
    
                Console.Read();
    
                // 刷新流并关闭
                Trace.Flush();
                listener.Close();
            }

    这里要注意,TextWriterTraceListener类用完后要调用Close或Flush方法,或者Dispose方法,又或者调用Trace类的Flush方法,反正你任选一种方案吧。因为需要这样做之后,数据才会最后写入到文件中,不然,文件是空白的。

    运行示例过后,再打开app.log文件,得到在下文本。

    有没有发现,配置日志文件路径写在代码中不太好玩,因为更改路径和文件名后就要重新编译,不如,考虑写在配置文件中吧。

    打开配置文件,输入以下内容:

    <configuration>
       ……
      <system.diagnostics>
        <trace autoflush="true">
          <listeners>
            <clear/>
            <add name="test" type="System.Diagnostics.TextWriterTraceListener" initializeData="D:TheApp.log"/>
          </listeners>
        </trace>
      </system.diagnostics>
    </configuration>

    下面给大伙分析一下这配置文件的规律。

    第一,你想想,我们刚刚讲的那些类都在哪个命名空间下?对了,System.Diagnostics,所以,对应地,在配置节中名为system.diagnostics。

    第二、Trace是与跟踪信息有关,所以下一个节点是trace。

    第三、前面我说过,Trace和Debug类都有一个Listeners集合,用来放监听器,是吧,所以下一子级就需要一个listeners节点。

    第四、listeners是个集合吧,所以它应该可以添加元素,删除元素,清除元素。这就对了,add用来添加监听器;remove用来删除监听器;clear就是清空集合,等于调用Clear方法。

    所以,上面配置中,clear就是把合集先清空,然后用add来加元素。name指定监听器的名字,这个你可以自己取,最好不要叫“Default”,刚说过了嘛,默认的监听器叫“Default”,你没必要非要用这个名字,你可以叫它“孙悟空”。

    type指定监听器的类型,一定要包含命名空间和类名,程序集中的version和pubKey这些可以不写。

    initializeData是传递给TextWriterTraceListener类构造函数的数据,对它来说,应该传入日志文件路径。我这里就把它存到D盘下面,你可以根据你的实际情况来定。

    注意:trace元素的autoflush设为true,推荐这么干,这样会自动调用Flush方法,从而让数据及时写入日志文件。

    以后,你想更改日志文件路径,只要改改配置文件就行了,不必重新编译代码。

    现在,这个配置你会写了吧,结构都懂了吧,而且VS还有智能提示的。要是这样你还不会写,那老周只好投降了。

    好,配置弄好了,咱们写几句代码耍耍。

            static void Main(string[] args)
            {
                Trace.WriteLine("好玩。");
                Trace.WriteLine("再写一行。");
                Trace.WriteLine("Write a new line again.");
            }

    运行应用程序,运行完后,打开日志文件,会看到这样:

    好了,今天的任务完成了。

    经过党组织讨论决定,由于本文的示例代码实在太简单了,本文不提供示例源码文件。

  • 相关阅读:
    使用MVC模型的几个常见误区
    ModelViewControl
    真的简单,还是盲目乐观?
    Kernel Korner Why and How to Use Netlink Socket
    我们手机平台的几个基础模型
    彩信库(mmslib)设计备忘录
    消极状态集
    文摘《十三》
    文摘《十二》
    文摘《十一》
  • 原文地址:https://www.cnblogs.com/tcjiaan/p/5597675.html
Copyright © 2011-2022 走看看