[英]Writing Logs to an XML File with .NET
我將日志存儲在xml文件中...
在傳統的直接文本格式方法中,您通常只需要一個openFile ...然后使用writeLine方法......
如何將新條目添加到xml文檔結構中,就像使用文本文件方法一樣?
使用XmlWriter。
示例代碼:
public class Quote
{
public string symbol;
public double price;
public double change;
public int volume;
}
public void Run()
{
Quote q = new Quote
{
symbol = "fff",
price = 19.86,
change = 1.23,
volume = 190393,
};
WriteDocument(q);
}
public void WriteDocument(Quote q)
{
var settings = new System.Xml.XmlWriterSettings
{
OmitXmlDeclaration = true,
Indent= true
};
using (XmlWriter writer = XmlWriter.Create(Console.Out, settings))
{
writer.WriteStartElement("Stock");
writer.WriteAttributeString("Symbol", q.symbol);
writer.WriteElementString("Price", XmlConvert.ToString(q.price));
writer.WriteElementString("Change", XmlConvert.ToString(q.change));
writer.WriteElementString("Volume", XmlConvert.ToString(q.volume));
writer.WriteEndElement();
}
}
示例輸出:
<Stock Symbol="fff">
<Price>19.86</Price>
<Change>1.23</Change>
<Volume>190393</Volume>
</Stock>
有關詳細信息,請參閱使用XmlWriter編寫 。
以XML格式編寫日志文件的一個問題是,您不能只將行附加到文件的末尾,因為最后一行必須有一個關閉的根元素(使XML有效)
這篇由Filip De Vos撰寫的博客文章展示了一個很好的解決方案:
高性能寫入XML日志文件 (編輯:鏈接現已死亡,因此刪除)
基本上,您使用XML-include事物鏈接在一起的兩個XML文件:
頭文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log [
<!ENTITY loglines SYSTEM "loglines.xml">
]>
<log>
&loglines;
</log>
行文件 (在本例中,名為loglines.xml):
<logline date="2007-07-01 13:56:04.313" text="start process" />
<logline date="2007-07-01 13:56:25.837" text="do something" />
<logline date="2007-07-01 13:56:25.853" text="the end" />
然后,您可以在“行文件”中添加新行,但(大多數)XML解析器將能夠打開頭文件並正確讀取行。
Filip指出: 這個XML不會被地球上的每個XML解析器正確解析。 但我用過的所有解析器都能正確完成。
最重要的區別在於您考慮日志數據的方式。 在純文本文件中,您確實只是添加新行。 然而,XML是一種樹結構,你需要這樣思考。 您要添加的內容可能是另一個NODE,即:
<log>
<time>12:30:03 PST</time>
<user>joe</user>
<action>login</action>
<log>
因為它是一棵樹,你需要問的是你在哪個父節點上添加這個新節點。 這通常都在您的DTD中定義(Aka,您如何定義數據結構)。 希望這比使用什么庫更有幫助,因為一旦理解了這個原則,庫的界面應該更有意義。
為什么重新發明輪子? 將TraceSource類(System.Diagnostics)與XmlWriterTraceListener一起使用 。
很抱歉發布舊帖子的答案。 我很久以前就開發了同樣的東西。 在這里,我想在xml文件中明確地分享我的記錄器保存日志數據的完整代碼。
using System.IO;
using System.Xml;
using System.Threading;
public class BBALogger
{
public enum MsgType
{
Error ,
Info
}
public static BBALogger Instance
{
get
{
if (_Instance == null)
{
lock (_SyncRoot)
{
if (_Instance == null)
_Instance = new BBALogger();
}
}
return _Instance;
}
}
private static BBALogger _Instance;
private static object _SyncRoot = new Object();
private static ReaderWriterLockSlim _readWriteLock = new ReaderWriterLockSlim();
private BBALogger()
{
LogFileName = DateTime.Now.ToString("dd-MM-yyyy");
LogFileExtension = ".xml";
LogPath= Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\Log";
}
public StreamWriter Writer { get; set; }
public string LogPath { get; set; }
public string LogFileName { get; set; }
public string LogFileExtension { get; set; }
public string LogFile { get { return LogFileName + LogFileExtension; } }
public string LogFullPath { get { return Path.Combine(LogPath, LogFile); } }
public bool LogExists { get { return File.Exists(LogFullPath); } }
public void WriteToLog(String inLogMessage, MsgType msgtype)
{
_readWriteLock.EnterWriteLock();
try
{
LogFileName = DateTime.Now.ToString("dd-MM-yyyy");
if (!Directory.Exists(LogPath))
{
Directory.CreateDirectory(LogPath);
}
var settings = new System.Xml.XmlWriterSettings
{
OmitXmlDeclaration = true,
Indent = true
};
StringBuilder sbuilder = new StringBuilder();
using (StringWriter sw = new StringWriter(sbuilder))
{
using (XmlWriter w = XmlWriter.Create(sw, settings))
{
w.WriteStartElement("LogInfo");
w.WriteElementString("Time", DateTime.Now.ToString());
if (msgtype == MsgType.Error)
w.WriteElementString("Error", inLogMessage);
else if (msgtype == MsgType.Info)
w.WriteElementString("Info", inLogMessage);
w.WriteEndElement();
}
}
using (StreamWriter Writer = new StreamWriter(LogFullPath, true, Encoding.UTF8))
{
Writer.WriteLine(sbuilder.ToString());
}
}
catch (Exception ex)
{
}
finally
{
_readWriteLock.ExitWriteLock();
}
}
public static void Write(String inLogMessage, MsgType msgtype)
{
Instance.WriteToLog(inLogMessage, msgtype);
}
}
BBALogger.Write("pp1", BBALogger.MsgType.Error);
BBALogger.Write("pp2", BBALogger.MsgType.Error);
BBALogger.Write("pp3", BBALogger.MsgType.Info);
MessageBox.Show("done");
我的代碼可以幫助你和其他:)
如果沒有關於您正在做什么的更多信息,我只能提供一些基本的建議來嘗試。
大多數XML對象都有一個名為“AppendChild”的方法。 您可以使用此方法添加您創建的新節點,其中包含日志注釋。 此節點將顯示在項目列表的末尾。 您將使用所有日志節點所在的父元素作為要調用的對象。
希望有所幫助。
XML需要一個文檔元素(基本上是頂級標記開始和結束文檔)。 這意味着格式良好的XML文檔需要具有開頭和結尾,這聽起來不太適合日志,其中日志的當前“結束”不斷擴展。
除非您編寫批量自包含日志,並在短時間內編寫要記錄到一個文件的所有內容,否則我會考慮除XML以外的其他內容。
如果您正在編寫完成的工作單元的日志,或者在整個工作完成之前不需要檢查的日志,您可以使用您的方法 - 只需打開文件,寫入日志行,關閉文件時工作單位完成了。
要編輯xml文件,您還可以使用LINQ。 您可以在這里查看: http : //www.linqhelp.com/linq-tutorials/adding-to-xml-file-using-linq-and-c/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.