程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 【個人使用.Net類庫】(2)Log日志記錄類,.net日志記錄

【個人使用.Net類庫】(2)Log日志記錄類,.net日志記錄

編輯:C#入門知識

【個人使用.Net類庫】(2)Log日志記錄類,.net日志記錄


開發接口程序時,要保證程序穩定運行就要時刻監控接口程序發送和接收的數據,這就需要一個日志記錄的類將需要的信息記錄在日志文件中,便於自己維護接口程序。(Web系統也是如此,只是對應的日志實現比這個要復雜一點)。

剛開始考慮的比較少,沒有加入控制日志文件數量的功能。運行了一段時間,文件夾內的Log文件如下所示:

using System; using System.Collections; using System.IO; namespace DotNetCommon.Logger { /// <summary> /// 實現IComparer接口,實現文件按名稱降序排序 /// </summary> class FileSorter:IComparer { /// <summary> /// 繼承IComparer接口必須實現的方法 /// </summary> /// <param name="x">FileInfo文件x</param> /// <param name="y">FileInfo文件y</param> /// <returns></returns> public int Compare(object x, object y) { if (x == null && y == null) return 0; if (x == null) return -1; if (y == null) return 1; var xInfo = (FileInfo) x; var yInfo = (FileInfo) y; //按名稱降序排序 return String.Compare(yInfo.FullName, xInfo.FullName, StringComparison.Ordinal); } } }

接下來就是實現日志文件自動刪除。具體思路是,當創建一個新的日志文件時,檢測是否超出最大日志允許數量。若超出,使用上面定義的比較器刪除之。日志自動刪除代碼方法如下:

/// <summary>
        /// 刪除Log目錄多余的日志文件
        /// </summary>
        public void DeleteUnnecessaryLogFiles()
        {
            var path = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory + @"Log\");
            var fileInfos = path.GetFiles("*.log");
            Array.Sort(fileInfos, new FileSorter());
            if (fileInfos.Length <= (_maxLogNum - 1)) return;
            for (var i = _maxLogNum - 1; i < fileInfos.Length; i++)
            {
                var filepath = fileInfos[i].FullName;
                if (!File.Exists(filepath)) continue;
                try
                {
                    File.Delete(filepath);
                }
                catch (Exception)
                {

                    return;
                }
            }
        }

Log日志類具體代碼如下所示:

using System;
using System.IO;
using System.Text;

namespace DotNetCommon.Logger
{
    /// <summary>
    /// 類說明:日志記錄(文本記錄和byte數組記錄)
    /// 編碼人:鞠小軍
    /// 聯系方式:[email protected]
    /// </summary>
    class Log
    {
        /// <summary>
        /// 程序當前目錄
        /// </summary>
        private readonly DirectoryInfo _dir = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);
        /// <summary>
        /// 默認日志文件最大數量為20
        /// </summary>
        private readonly int _maxLogNum = 20;
        /// <summary>
        /// 構造函數
        /// </summary>
        /// <param name="maxLogNum">Log目錄下日志文件的最大數量</param>
        public Log(int maxLogNum)
        {
            _maxLogNum = maxLogNum;
        }

        /// <summary>
        /// 字符串寫入日志文件
        /// </summary>
        /// <param name="msg">寫入的字符串文本</param>
        public void WriteLog_Txt(string msg)
        {
            FileStream stream = null;
            var sb = new StringBuilder();
            var path = _dir + "Log";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            var str2 = path + @"\" + DateTime.Now.ToString("yyyy-MM-dd") + ".log";
            sb.Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " ");
            sb.Append(msg);
            var bytes = Encoding.UTF8.GetBytes(sb + "\r\n");
            try
            {
                if (!File.Exists(str2))
                    DeleteUnnecessaryLogFiles();
                stream = File.OpenWrite(str2);
                stream.Position = stream.Length;
                stream.Write(bytes, 0, bytes.Length);
            }
            catch (Exception exception)
            {
                Console.WriteLine("文件打開失敗{0}", exception.Message);
            }
            finally
            {
                if (stream != null) stream.Close();
            }
        }
        /// <summary>
        /// 字節數組寫入日志文件
        /// </summary>
        /// <param name="msg">提示信息</param>
        /// <param name="data">字節數組</param>
        public void WriteLog_Bytes(string msg, byte[] data)
        {
            FileStream stream = null;
            var sb = new StringBuilder();
            var path = _dir + @"\Log";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            var str2 = path + @"\" + DateTime.Now.ToString("yyyy-MM-dd") + ".log";
            sb.Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " ");
            sb.Append(msg);
            foreach (var num in data)
            {
                sb.AppendFormat("{0:x2} ", num);
            }
            var bytes = Encoding.UTF8.GetBytes(sb + "\r\n");
            try
            {
                if (!File.Exists(str2))
                    DeleteUnnecessaryLogFiles();
                stream = File.OpenWrite(str2);
                stream.Position = stream.Length;
                stream.Write(bytes, 0, bytes.Length);
            }
            catch (Exception exception)
            {
                Console.WriteLine("文件打開失敗{0}", exception.Message);
            }
            finally
            {
                if (stream != null) stream.Close();
            }
        }
        /// <summary>
        /// 刪除Log目錄多余的日志文件
        /// </summary>
        public void DeleteUnnecessaryLogFiles()
        {
            var path = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory + @"Log\");
            var fileInfos = path.GetFiles("*.log");
            Array.Sort(fileInfos, new FileSorter());
            if (fileInfos.Length <= (_maxLogNum - 1)) return;
            for (var i = _maxLogNum - 1; i < fileInfos.Length; i++)
            {
                var filepath = fileInfos[i].FullName;
                if (!File.Exists(filepath)) continue;
                try
                {
                    File.Delete(filepath);
                }
                catch (Exception)
                {

                    return;
                }
            }
        }
    }
}

當前日志類不夠完善,我還沒有加上文件超過固定大小(如超出2M)自動創建新文件等等必要的功能,後續會逐漸完善。大家有什麼好建議,歡迎大家拍磚,哈哈。


String類與StringBuilder類有什不同?為何在Net類庫中要同時存在這2個類?拜托各位

如果要操作一個不斷增長的字符串,盡量不用String類,改用StringBuilder類。兩個類的工作原理不同:String類是一種傳統的修改字符串的方式,它確實可以完成把一個字符串添加到另一個字符串上的工作沒錯,但是在.NET框架下,這個操作實在是劃不來。因為系統先是把兩個字符串寫入內存,接著刪除原來的String對象,然後創建一個String對象,並讀取內存中的數據賦給該對象。這一來二去的,耗了不少時間。而使用System.Text命名空間下面的StringBuilder類就不是這樣了,它提供的Append方法,能夠在已有對象的原地進行字符串的修改,簡單而且直接。當然,一般情況下覺察不到這二者效率的差異,但如果你要對某個字符串進行大量的添加操作,那麼StringBuilder類所耗費的時間和String類簡直不是一個數量級的。
 

String類與StringBuilder類有什不同?為何在Net類庫中要同時存在這2個類?

  String是一個Unicode字符的有序集合,用於表示文本。一個字符串對象的有序集合系統.。字符對象代表一個字符串。字符串的值對象的內容是有序集合,這個價值是不可變的。  一個字符串對象稱為不變的(只讀),因為它的價值不能修改一旦建立。方法,似乎修改一個字符串對象實際上會返回一個新字符串對象,其中包含修改;

StringBuilder這個類代表一個可變的字符序列。據說這個值是可變的,因為它可以修改一旦建立通過添加,刪除,替換,或者插入字符。相比之下,看到String類。  大部分的方法,這些方法可以修改這個類的實例返回一個引用相同的實例。因為一個引用返回的實例,可以調用一個方法或屬性引用。這可以方便,如果你想寫一個聲明,一個接一個鏈連續操作。  一個StringBuilder的能力的最大字符數的實例可以存儲在任何給定的時間,和大於或等於字符串的長度表示值的實例;

如果有必要修改實際內容的一個線狀對象,使用StringBuilder類。 
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved