C# 写入Filestream并复制到MemoryStream
我想在磁盘上覆盖或创建一个xml文件,并从函数返回xml。我想我可以通过从FileStream复制到MemoryStream来实现这一点。但我最终将一个新的xml文档附加到同一个文件中,而不是每次都创建一个新文件。 我做错了什么?如果我删除了拷贝,一切正常C# 写入Filestream并复制到MemoryStream,c#,.net,xml,C#,.net,Xml,我想在磁盘上覆盖或创建一个xml文件,并从函数返回xml。我想我可以通过从FileStream复制到MemoryStream来实现这一点。但我最终将一个新的xml文档附加到同一个文件中,而不是每次都创建一个新文件。 我做错了什么?如果我删除了拷贝,一切正常 public static string CreateAndSave(IEnumerable<OrderPage> orderPages, string filePath) { if (orderPage
public static string CreateAndSave(IEnumerable<OrderPage> orderPages, string filePath)
{
if (orderPages == null || !orderPages.Any())
{
return string.Empty;
}
var xmlBuilder = new StringBuilder();
var writerSettings = new XmlWriterSettings
{
Indent = true,
Encoding = Encoding.GetEncoding("ISO-8859-1"),
CheckCharacters = false,
ConformanceLevel = ConformanceLevel.Document
};
using (var fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
try
{
XmlWriter xmlWriter = XmlWriter.Create(fs, writerSettings);
xmlWriter.WriteStartElement("PRINT_JOB");
WriteXmlAttribute(xmlWriter, "TYPE", "Order Confirmations");
foreach (var page in orderPages)
{
xmlWriter.WriteStartElement("PAGE");
WriteXmlAttribute(xmlWriter, "FORM_TYPE", page.OrderType);
var outBound = page.Orders.SingleOrDefault(x => x.FlightInfo.Direction == FlightDirection.Outbound);
var homeBound = page.Orders.SingleOrDefault(x => x.FlightInfo.Direction == FlightDirection.Homebound);
WriteXmlOrder(xmlWriter, outBound, page.ContailDetails, page.UserId, page.PrintType, FlightDirection.Outbound);
WriteXmlOrder(xmlWriter, homeBound, page.ContailDetails, page.UserId, page.PrintType, FlightDirection.Homebound);
xmlWriter.WriteEndElement();
}
xmlWriter.WriteFullEndElement();
MemoryStream destination = new MemoryStream();
fs.CopyTo(destination);
Log.Progress("Xml string length: {0}", destination.Length);
xmlBuilder.Append(Encoding.UTF8.GetString(destination.ToArray()));
destination.Flush();
destination.Close();
xmlWriter.Flush();
xmlWriter.Close();
}
catch (Exception ex)
{
Log.Warning(ex, "Unhandled exception occured during create of xml. {0}", ex.Message);
throw;
}
fs.Flush();
fs.Close();
}
return xmlBuilder.ToString();
}
public静态字符串CreateAndSave(IEnumerable orderPages,字符串文件路径)
{
if(orderPages==null | |!orderPages.Any())
{
返回字符串。空;
}
var xmlBuilder=新的StringBuilder();
var writerSettings=新的XmlWriterSettings
{
缩进=真,
Encoding=Encoding.GetEncoding(“ISO-8859-1”),
CheckCharacters=false,
ConformanceLevel=ConformanceLevel.Document
};
使用(var fs=new FileStream(filePath,FileMode.OpenOrCreate,FileAccess.ReadWrite))
{
尝试
{
XmlWriter=XmlWriter.Create(fs,writerSettings);
writeStart元素(“打印作业”);
WriteXmlAttribute(xmlWriter,“类型”,“订单确认”);
foreach(orderPages中的变量页)
{
writeStart元素(“页面”);
WriteXmlAttribute(xmlWriter,“表单类型”,page.OrderType);
var outBound=page.Orders.SingleOrDefault(x=>x.FlightInfo.Direction==FlightDirection.outBound);
var homeboond=page.Orders.SingleOrDefault(x=>x.FlightInfo.Direction==FlightDirection.homeboond);
WriteXmlOrder(xmlWriter,出站,page.ContailDetails,page.UserId,page.PrintType,FlightDirection.outBound);
WriteXmlOrder(xmlWriter,homeBound,page.ContailDetails,page.UserId,page.PrintType,FlightDirection.homeBound);
xmlWriter.WriteEndElement();
}
xmlWriter.WriteFileLendElement();
MemoryStream destination=新的MemoryStream();
财政司司长(目的地);
Progress(“Xml字符串长度:{0}”,destination.length);
Append(Encoding.UTF8.GetString(destination.ToArray());
destination.Flush();
destination.Close();
xmlWriter.Flush();
xmlWriter.Close();
}
捕获(例外情况除外)
{
Log.Warning(例如,“创建xml.{0}期间发生未处理的异常”,例如Message);
投掷;
}
fs.Flush();
fs.Close();
}
返回xmlBuilder.ToString();
}
干杯
Jens
文件模式。OpenOrCreate
会导致文件内容被覆盖而不会缩短,从而保留以前运行的任何“尾随”数据。如果使用FileMode.Create
,文件将首先被截断。但是,要读回刚才编写的内容,需要使用Seek
重置文件指针
另外,在从底层流复制之前,刷新XmlWriter
另见问题
下面的测试程序似乎可以满足您的要求(减少您自己的日志记录和订单详细信息)
FileMode.OpenOrCreate
导致文件内容被覆盖而不会缩短,从而保留以前运行的任何“尾随”数据。如果使用FileMode.Create
,文件将首先被截断。但是,要读回刚才编写的内容,需要使用Seek
重置文件指针
另外,在从底层流复制之前,刷新XmlWriter
另见问题
下面的测试程序似乎可以满足您的要求(减少您自己的日志记录和订单详细信息)
FileMode.OpenOrCreate
导致文件内容被覆盖而不会缩短,从而保留以前运行的任何“尾随”数据。如果使用FileMode.Create
,文件将首先被截断。但是,要读回刚才编写的内容,需要使用Seek
重置文件指针
另外,在从底层流复制之前,刷新XmlWriter
另见问题
下面的测试程序似乎可以满足您的要求(减少您自己的日志记录和订单详细信息)
FileMode.OpenOrCreate
导致文件内容被覆盖而不会缩短,从而保留以前运行的任何“尾随”数据。如果使用FileMode.Create
,文件将首先被截断。但是,要读回刚才编写的内容,需要使用Seek
重置文件指针
另外,在从底层流复制之前,刷新XmlWriter
另见问题
下面的测试程序似乎可以满足您的要求(减少您自己的日志记录和订单详细信息)
我知道我迟到了,但似乎有一个更简单的解决办法。您希望函数生成xml,将其写入文件并返回生成的xml。显然,分配
字符串
是不可避免的(因为您希望返回该字符串),写入文件也是如此。但是,通过简单地“交换”操作(生成xml字符串并将其写入文件),可以很容易地避免读取文件(如您和SensorSmith的解决方案)。像这样:
var output = new StringBuilder();
var writerSettings = new XmlWriterSettings { /* your settings ... */ };
using (var xmlWriter = XmlWriter.Create(output, writerSettings))
{
// Your xml generation code using the writer
// ...
// You don't need to flush the writer, it will be done automatically
}
// Here the output variable contains the xml, let's take it...
var xml = output.ToString();
// write it to a file...
File.WriteAllText(filePath, xml);
// and we are done :-)
return xml;
重要更新:结果是
XmlWriter.Create(StringBuider,XmlWriterSettings)
重载忽略设置中的编码,并始终使用“utf-16”,因此如果需要其他编码,请不要使用此方法 我知道我迟到了,但似乎有一个更简单的解决办法。您希望函数生成xml,将其写入文件并返回生成的xml。幻影
public static string CreateAndSave(IEnumerable<string> orderPages, string filePath)
{
if (orderPages == null || !orderPages.Any())
{
return string.Empty;
}
string result;
var writerSettings = new XmlWriterSettings
{
Indent = true,
Encoding = Encoding.GetEncoding("ISO-8859-1"),
CheckCharacters = false,
ConformanceLevel = ConformanceLevel.Document
};
using (var fs = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite))
{
try
{
XmlWriter xmlWriter = XmlWriter.Create(fs, writerSettings);
xmlWriter.WriteStartElement("PRINT_JOB");
foreach (var page in orderPages)
{
xmlWriter.WriteElementString("PAGE", page);
}
xmlWriter.WriteFullEndElement();
xmlWriter.Close(); // Flush from xmlWriter to fs
fs.Seek(0, SeekOrigin.Begin); // Go back to read from the begining
var reader = new StreamReader(fs, writerSettings.Encoding);
result = reader.ReadToEnd();
// reader.Close(); // This would just flush/close fs early(which would be OK)
}
catch (Exception ex)
{
throw;
}
}
return result;
}
var output = new StringBuilder();
var writerSettings = new XmlWriterSettings { /* your settings ... */ };
using (var xmlWriter = XmlWriter.Create(output, writerSettings))
{
// Your xml generation code using the writer
// ...
// You don't need to flush the writer, it will be done automatically
}
// Here the output variable contains the xml, let's take it...
var xml = output.ToString();
// write it to a file...
File.WriteAllText(filePath, xml);
// and we are done :-)
return xml;