文件流写入异常,,,,非常奇怪的问题~!!!!! 高人进来~~

taoyi 2005-06-17 10:21:21
由于使用XmlDocument类操作XML文件出现共享冲突的问题,所以我从XmlDocument类继承了一个类,并覆盖了XmlDocument类的Load和Save方法,希望以此解决多个进程同时访问XML时出现共享冲突的问题,代码如下:

public class XmlDocumentEx : System.Xml.XmlDocument
{
public XmlDocumentEx() : base()
{
}

public new void Load(string filename)
{
FileStream fs = null;

try
{
lock(this)
{
fs = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
string str = "";
byte[] buf = new byte[fs.Length];
int len = 0;
Encoding encoding = Encoding.GetEncoding(936);
while ((len = fs.Read(buf, 0, buf.Length)) != 0)
{
str += encoding.GetString(buf);
}
base.LoadXml(str);
}
}
catch
{
throw;
}
finally
{
fs.Close();
}
}

public new void Save(string filename)
{
FileStream fs = null;

try
{
lock(this)
{
fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
Encoding encoding = Encoding.GetEncoding(936);
byte[] result = encoding.GetBytes(base.InnerXml);
fs.Write(result, 0, result.Length);
}
}
catch
{
throw;
}
finally
{
fs.Close();
}
}
}

使用这段代码后,,共享冲突的问题倒是解决了,可郁闷的是在调用Save方法写入文件的时候老是不正常,,总会多出一段,如本来内容为:
<?xml.....?>
<base>
<xx />
<..../>
<test />
</base>

结果增加一个节点后却成了:
<?xml.....?>
<base>
<xx />
<..../>
<test />
<newnode /> <--新增的节点
</base>
node /> <-- 多出一部分了
</base>

请问这是什么原因造成的,,该如何解决???几乎所有的文件操作方式我都试过了,都出问题,晕死掉了~~
...全文
286 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
taoyi 2005-06-17
  • 打赏
  • 举报
回复
果真,,,谢谢fancyf(凡瑞) !!!
fanruinet 2005-06-17
  • 打赏
  • 举报
回复
把fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
中的FileMode改成Truncate,那几个多出来的标签是前面文件的后半部分,因为重写以后空格回车都没了,文件变小了,但是原来文件的内容还在,用Truncate把原文件的内容都清楚再写就好了
taoyi 2005-06-17
  • 打赏
  • 举报
回复
byte[] result = encoding.GetBytes(base.InnerXml);
fs.Write(result, 0, result.Length);

不会,,在Write之前的InnerXml的内容绝对是正确的,我跟踪过了的~,可写入后文件就不对了~
marvelstack 2005-06-17
  • 打赏
  • 举报
回复
检查你加载到XmlDocument文档后对其的操作是否增加了多出来的节点。
或者可以试试Load后就Save看看是否有所变化。
taoyi 2005-06-17
  • 打赏
  • 举报
回复
?xml version="1.0" encoding="gb2312"?>
<server>
<base>
<netBarID>100004</netBarID>
<name>xx</name>
<password>e72294d781e440060372689cfd9de94d</password>
<setupPath>xx(C:\netbar)</setupPath>
<wsAddress>
</wsAddress>
<serverVersion>2.0</serverVersion>
<clientVersion>2.0</clientVersion>
</base>
<client>
<clientItem id="1" ip="192.168.0.47" lastUseDate="2005-5-31" using="1" />
</client>
<orderType>
<item id="1011" name="name" lib="GlobalComponent" />
<item id="1013" name="" lib="GlobalComponent" />
<item id="1014" name="" lib="GlobalComponent" />
<item id="1015" name="" lib="GlobalComponent" />
<item id="1016" name="" lib="GlobalComponent" />
<item id="1018" name="" lib="GlobalComponent" />
<item id="2005" name="" lib="WSGComponent" />
<item id="2001" name="" lib="WSGComponent" />
<item id="4001" name="" lib="GlobalComponent" />
<item id="3001" name="" lib="WSGComponent" />
<item id="3002" name="" lib="WSGComponent" />
<item id="2002" name="" lib="WSGComponent" />
<item id="2003" name="" lib="GlobalComponent" />
<item id="2004" name="" lib="WSGComponent" />
<item id="4002" name="" lib="WSGComponent" />
<item id="3003" name="" lib="WSGComponent" />
<item id="3004" name="" lib="WSGComponent" />
<item id="10000" name="" lib="WSGComponent" />
<item id="2006" name="" lib="WSGComponent" />
</orderType>
<order>
<timing>
<item name="SearchCommand" orderCode="10000" sys="1" time="1" />
<item name="DownloadAffiche" orderCode="2005" sys="1" time="1" />
<item name="UploadTerminalCount" orderCode="3001" sys="1" time="1" />
<item name="UploadTerminalOnlineCount" orderCode="3002" sys="1" time="1" />
<item name="UploadMovieHit" orderCode="3003" sys="1" time="1" />
<item name="UploadMovieTop" orderCode="2006" sys="1" time="1" />
<item name="SendLogFile" orderCode="3004" sys="1" time="10" />
</timing>
<task>
</task>
<job>
</job>
</order>
</server>

使用上面的XML文件,然后用下面的代码测试:
XmlDocumentEx doc = new XmlDocumentEx();
doc.Load(file);

XmlElement item = doc.CreateElement("", JOB_ITEM, "");
item.SetAttribute("ordercode", "1000");
item.SetAttribute("sys", "1");
item.SetAttribute("time", "xx");

XmlNode node = doc.DocumentElement.SelectSingleNode("order/job");
node.AppendChild(item);

doc.Save(file);
fanruinet 2005-06-17
  • 打赏
  • 举报
回复
我用你这段代码运行怎么没发现多出来的节点呢?
taoyi 2005-06-17
  • 打赏
  • 举报
回复
楼上的大哥还是MM?我是这样增加节点的:

string file = "xx.xml";
XmlDocumentEx doc = new XmlDocumentEx();
doc.Load(file);
XmlElement node = doc.CreateElement("newnode");
doc.DocumentElement.AppendChild(node);
doc.Save(file);

这样有什么不对吗??请解释~~~
givenchy 2005-06-17
  • 打赏
  • 举报
回复
怎么能这样写增加节点呢。
taoyi 2005-06-17
  • 打赏
  • 举报
回复
郁闷啦,,,,,咋就没热心人呢????

我急啊........
taoyi 2005-06-17
  • 打赏
  • 举报
回复
但是单个对象写入时也不正确啊,,,郁闷啦~~~

造成这样的原因是什么呢?我确定写的时候只有一个打开的文件句柄
fanruinet 2005-06-17
  • 打赏
  • 举报
回复
你用fs = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);这种方式很危险,不知道你的系统中是否会同时存在多个XmlDocumentEx对象,如果是这样的话,lock(this)只能锁住一个对象,但是其他线程仍然可以通过其它对象对这个文件进行操作。
建议把FileShare.ReadWrite改为None,起码是.Read
taoyi 2005-06-17
  • 打赏
  • 举报
回复
咋就没人理我呢?
是太简单了吗?简单也给我指个路啊~~各位大哥~!!

111,094

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧