C# 写入Filestream并复制到MemoryStream

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

我想在磁盘上覆盖或创建一个xml文件,并从函数返回xml。我想我可以通过从FileStream复制到MemoryStream来实现这一点。但我最终将一个新的xml文档附加到同一个文件中,而不是每次都创建一个新文件。 我做错了什么?如果我删除了拷贝,一切正常

 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;