2014-07-11 6 views
5

में बड़ी संख्या में रिकॉर्ड्स के साथ डाउनलोड के लिए एक्सएमएल फ़ाइल प्रदान करें, मुझे 6,00,000 रिकॉर्ड (डेटा बढ़ सकता है) के साथ डाउनलोड करने के लिए एक्सएमएल फ़ाइल प्रदान करने की आवश्यकता है, लेकिन डिस्क पर फ़ाइल को सहेजने की अनुमति नहीं है। मैं सीधे एक्सएमएल लिखित रूप में इस मुद्दे का सामना करना पड़ रहा था तो & स्ट्रीम करने के लिए डाउनलोड के लिए उपलब्ध कराने के, तो मैं पहले इसे करने के लिए डिस्क & लेखन डेटा पर xml फ़ाइल बनाया है और बाई & डाउनलोड के लिए उपलब्ध कराने में इसे पढ़ने के लिए कोशिश कर रहा है और उसके बाद डिस्क से फ़ाइल को नष्ट । लेकिन में "system.outofmemoryexception" प्राप्त करना "बाइट [] b = File.ReadAllBytes (filepath);"।एएसपीनेट सी #

string name = string.Format("{0:yyyyMMddHHmmss}", DateTime.Now); 
string filename = "TestFile.xml"; 

string filepath = ConfigurationManager.AppSettings["XmlFiles"] + "\\" + filename; 


DataTable dataTable = dsData.Tables[0];    

FileStream fs =new FileStream(filepath, FileMode.Create); 
XmlWriterSettings xws = new XmlWriterSettings { OmitXmlDeclaration = true }; 
using (XmlWriter xmlWriter = XmlWriter.Create(fs,xws)) 
{ 

    xmlWriter.WriteStartElement("root"); 

    foreach (DataRow dataRow in dataTable.Rows) 
    { 
    xmlWriter.WriteStartElement("datanode"); 
    foreach (DataColumn dataColumn in dataTable.Columns) 
    { 
    xmlWriter.WriteElementString(dataColumn.ColumnName.Replace("\n\r", " ") 
            .Replace("\n", " ").Replace("\r", " "), Convert.ToString(dataRow[dataColumn]).Replace("\n\r", " ").Replace("\n", " ").Replace("\r", " ")); 
         } 

     xmlWriter.WriteEndElement(); 
    } 
    xmlWriter.WriteEndElement(); 
    xmlWriter.Flush(); 
    xmlWriter.Close(); 
    } 

    fs.Close(); 
    Byte[] b = File.ReadAllBytes(filepath);     
    if (File.Exists(filepath)) 
     File.Delete(filepath); 

string s = string.Format("{0:yyyyMMddHHmmss}", DateTime.Now); 
HttpContext.Current.Response.ContentType = "application/xml"; 
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8; 
HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment; filename=" + s + ".xml" + ""); 
HttpContext.Current.Response.BinaryWrite(b); 
HttpContext.Current.Response.End(); 

वहाँ किसी अन्य तरीके से रिकॉर्ड की बड़ी संख्या को संभालने के लिए है:

नीचे मेरी कोड है?

+0

शायद [इस] (http://stackoverflow.com/questions/2809514/outofmemoryexception-when-i-read-filestream-500-mb) धागा तुम्हारी मदद करेगा। –

+0

धन्यवाद @ टोबियास जोहानसन, मैं यह जांचूंगा। – GMD

उत्तर

2

आप सीधे इंटरमीडिएट फ़ाइल की आवश्यकता के बिना XmlWriter को प्रतिक्रिया OutputStream पर हुक अप कर सकते हैं। BufferOutput से false पर सेट करके आप क्लाइंट को भेजने से पहले पूर्ण repsonse सर्वर पक्ष buffered है।

ध्यान दें कि एकाधिक प्रतिस्थापन बयान अतिरिक्त स्मृति दबाव/जीसी-एड होने के लिए और अधिक तारों का कारण बनेंगे।

string name = string.Format("attachment; filename={0:yyyyMMddHHmmss}.xml", DateTime.Now); 
HttpContext.Current.Response.ContentType = "application/xml"; 
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8; 

HttpContext.Current.Response.BufferOutput = false; //start streaming immideately 

HttpContext.Current.Response.AppendHeader("Content-Disposition", name); 

DataTable dataTable = dsData.Tables[0];    

XmlWriterSettings xws = new XmlWriterSettings { OmitXmlDeclaration = true }; 

using (XmlWriter xmlWriter = XmlWriter.Create(
     HttpContext.Current.Response.OutputStream, // The OutputStream of the HttpResponse 
     xws)) 
{ 
    xmlWriter.WriteStartElement("root"); 

    var cleanedColNames = new Dictionary<DataColumn, string>(); 
    foreach (DataColumn dataColumn in dataTable.Columns) 
    { 
     cleanedColNames.Add(dataColumn, 
      dataColumn.ColumnName.Replace("\n\r", " ") 
           .Replace("\n", " ") 
           .Replace("\r", " ")); 
    } 

    foreach (DataRow dataRow in dataTable.Rows) 
    { 
    xmlWriter.WriteStartElement("datanode"); 
    foreach (DataColumn dataColumn in dataTable.Columns) 
    { 
     xmlWriter.WriteElementString(
      cleanedColNames[dataColumn], 
      Convert.ToString(dataRow[dataColumn]).Replace("\n\r", " ") 
                .Replace("\n", " ") 
                .Replace("\r", " ")); 
         } 
     xmlWriter.WriteEndElement(); 
    } 
    xmlWriter.WriteEndElement(); 
    xmlWriter.Flush(); 
    xmlWriter.Close(); 
    } 

HttpContext.Current.Response.End(); 
+0

अगर फ़ाइल बड़ी है तो क्या प्रतिक्रिया आउटपुटस्ट्रीम का उपयोग करना ठीक होगा? मुझे संदेह है कि यह अधिक कैश पर कब्जा करेगा। – GMD

+1

मैंने सर्वरसाइड बफरिंग को रोकने के लिए बफरऑटपुट के लिए एक अतिरिक्त सेटिंग जोड़ा। मुझे पूरा यकीन है कि मेरा समाधान आपकी तुलना में कम स्मृति का उपयोग करता है। ध्यान दें कि आपके प्रतिस्थापन बयान मेमोरी दबाव भी पैदा करते हैं। – rene

+0

यह काम करता है, और प्रतिस्थापन कथन के लिए मुझे इसे कुछ स्ट्रिंग कॉलम के लिए रखना होगा, बाकी के लिए मैं इसे हटा दूंगा। – GMD