2010-12-31 18 views
24

डाउनलोड करें मैं स्मृति में एक टेक्स्ट फ़ाइल को लिखने की कोशिश कर रहा हूं और फिर फ़ाइल को हार्ड डिस्क पर सहेजने के बिना उस फ़ाइल को डाउनलोड कर रहा हूं।टेक्स्ट फ़ाइल बनाएं और

StringWriter oStringWriter = new StringWriter(); 
oStringWriter.Write("This is the content"); 

कैसे मैं तो यह फ़ाइल डाउनलोड करते हैं: मैं StringWriter सामग्री लिखने के लिए उपयोग कर रहा हूँ?

संपादित करें: यह उन उत्तरों का संयोजन था जिसने मुझे अपना समाधान दिया। संदेश यह है:

StringWriter oStringWriter = new StringWriter(); 
oStringWriter.WriteLine("Line 1"); 
Response.ContentType = "text/plain"; 

Response.AddHeader("content-disposition", "attachment;filename=" + string.Format("members-{0}.csv",string.Format("{0:ddMMyyyy}",DateTime.Today))); 
Response.Clear(); 

using (StreamWriter writer = new StreamWriter(Response.OutputStream, Encoding.UTF8)) 
{ 
    writer.Write(oStringWriter.ToString()); 
} 
Response.End(); 
+0

http://www.xefteri.com/articles/show.cfm?id=8 – fejesjoco

उत्तर

13

इसके बजाय की स्मृति में डेटा संग्रहीत करने और फिर इसे प्रतिक्रिया स्ट्रीम करने के लिए भेजते समय, आप लिख सकते हैं यह सीधे प्रतिक्रिया स्ट्रीम करने के लिए:

using (StreamWriter writer = new StreamWriter(Response.OutputStream, Encoding.UTF8)) { 
    writer.Write("This is the content"); 
} 

उदाहरण UTF-8 एन्कोडिंग का उपयोग करता है, तो आप बदलना चाहिए कि आप कुछ अन्य एन्कोडिंग का उपयोग कर रहे हैं।

+0

हाय गुफा - फिर मैं डाउनलोड करने के लिए प्रतिक्रिया स्ट्रीम कैसे प्राप्त करूं? – higgsy

+0

@higgsy: इतना है कि ब्राउज़र पता है कि यह क्या है आप शीर्षक में सामग्री स्वभाव और सामग्री प्रकार के लिए निर्देश जोड़ने के लिए,। क्लाउस बिस्को हॉफमैन के पास उनके जवाब में कुछ उदाहरण हैं, लेकिन प्रतिक्रिया को वापस करने के लिए आपको HTTP हैंडलर का उपयोग करने की आवश्यकता नहीं है, यह नियमित पृष्ठ के साथ भी काम करता है। आपको सामग्री प्रकार में एन्कोडिंग भी निर्दिष्ट करनी चाहिए, उदाहरण के लिए 'टेक्स्ट/सादा; charset = utf-8'। – Guffa

0

यह बहुत सरल है, और जवाब इस Microsoft KB आलेख में देखा जा सकता: How to write binary files to the browser using ASP.NET and C#

+0

यह वास्तव में सवाल ... higgsy निर्दिष्ट है कि फाइल मुश्किल के लिए नहीं लिखा जाना चाहिए का उत्तर न मिले डिस्क। – BG100

+2

हाय, ठीक, फ़ाइल हार्ड ड्राइव करने के लिए नहीं लिखा जाना चाहिए। – higgsy

5

मूल रूप से आप IHttpHandler इंटरफेस को लागू करने से बनाने के एक HttpHandler। ProcessRequest विधि में आप मूल रूप से बस अपना टेक्स्ट context.Response पर लिखें। तुम भी एक Content-Disposition HTTP शीर्ष लेख जोड़ने की जरूरत:

context.Response.AddHeader("Content-Disposition", "attachment; filename=YourFileName.txt"); 

भी स्थापित करने के लिए याद ContentType:

context.Response.ContentType = "text/plain"; 
2

अन्य उत्तरों के लिए बस एक छोटा सा अतिरिक्त। डाउनलोड के बहुत अंत में मैं निष्पादित करता हूं:

context.Response.Flush(); 
context.ApplicationInstance.CompleteRequest(); 

मैंने सीखा कि अन्यथा, डाउनलोड कभी-कभी सफलतापूर्वक पूर्ण नहीं होता है।

This Google Groups posting यह भी नोट करता है कि Response.EndThreadAbortException फेंकता है जो आप CompleteRequest विधि का उपयोग करके बच सकते हैं।

+1

असल में जब मैंने आपके द्वारा जोड़े गए लाइनों का उपयोग किया था, जेनरेट की गई फ़ाइल में मैंने जो पाठ लिखा था, जिसमें मैंने स्ट्रीम किया था और साथ ही एचटीएमएल कोड भी लिखा था, इसलिए मुझे कोड में वापस जाना पड़ा और बस "Response.End" लाइन डाली और यह काम किया बस ठीक ! – Glolita

+1

आमतौर पर, मैं केवल अलग एएसएचएक्स हैंडलर के माध्यम से डाउनलोड प्रदान करता हूं, एएसपीएक्स पृष्ठों में नहीं। –

16

यह मेरे लिए हल:

 MemoryStream ms = new MemoryStream(); 
     TextWriter tw = new StreamWriter(ms); 
     tw.WriteLine("Line 1"); 
     tw.WriteLine("Line 2"); 
     tw.WriteLine("Line 3"); 
     tw.Flush(); 
     byte[] bytes = ms.ToArray(); 
     ms.Close(); 

     Response.Clear(); 
     Response.ContentType = "application/force-download"; 
     Response.AddHeader("content-disposition", "attachment; filename=file.txt"); 
     Response.BinaryWrite(bytes); 
     Response.End();  
0

मैं इस के साथ कई मुद्दों था। फिनली को एक समाधान मिला जो हर समय काम करता प्रतीत होता है।

ज्यादातर मामलों में उपयोगकर्ता डाउनलोड के लिए एक बटन क्लिक करने जा रहा है। इस बिंदु पर पृष्ठ को उसी स्थान पर रीडायरेक्ट करना सबसे अच्छा है। यूआरएल में एक पैरामीटर जोड़ें जिसे आप पकड़ और पढ़ सकते हैं।

उदाहरण (www.somewhere.com/mypage.aspx?print=stuff)

<asp:Button ID="btn" runat="server" Text="print something" OnClick="btn_Click" /> 


    protected void Page_Load(object sender, EventArgs e) { 
     if (Request["print"] == "stuff") { Print("my test content"); } 
    } 

    /* or pass byte[] content*/ 
    private void Print(string content){ 
     Response.ContentType = "text/plain"; 
     Response.AddHeader("content-disposition", "attachment;filename=myFile.txt"); 
     // Response.BinaryWrite(content); 
     Response.Write(content); 
     Response.Flush(); 
     Response.End(); 
    } 

    protected void btn_Click(object sender, EventArgs e) { 
     // postbacks give you troubles if using async. 
     // Will give an error when Response.End() is called. 
     Response.Redirect(Request.Url + "?print=queue"); 
    } 
0

@Vinicious जवाब का विस्तार।

मेरे पास डेटा था जिसमें अल्पविराम शामिल हो सकता था। सामान्य समाधान उद्धरण में संलग्न करके डेटा के उस टुकड़े से बचने के लिए है, जबकि यह सुनिश्चित करना कि डेटा का हिस्सा भी हो सकता है।

सीएसवी लिखते समय मैं एक रगड़ और चेतावनी के खिलाफ आया, अगर आप अपने कॉमा का पीछा करते हुए रिक्त स्थान डालते हैं तो एक्सेल आपको पसंद नहीं करेगा।discovered solution to my problem from superuser answer

protected void btnDownload_Click(object sender, EventArgs e) 
{ 
    MemoryStream ms = new MemoryStream(); 
    TextWriter tw = new StreamWriter(ms, System.Text.Encoding.UTF8); 
    var structures = KAWSLib.BusinessLayer.Structure.GetStructuresInService(); 
    // *** comma delimited 
    tw.Write("Latitude, Longitude, CountySerial, StructureType, Orientation, District, RoutePre, RouteNo, LocationDesc"); 
    foreach (var s in structures) 
    { 
     tw.Write(Environment.NewLine + string.Format("{0:#.000000},{1:#.000000},{2},{3},{4},{5},{6},{7},{8}", s.LATITUDE, s.LONGITUDE, s.CO_SER, EscapeIfNeeded(s.SuperTypeLookup.SHORTDESC), EscapeIfNeeded(s.OrientationLookup.SHORTDESC), s.DISTRICT, s.ROUTE_PREFIX, s.RouteValue, EscapeIfNeeded(s.LOC_DESC))); 
    } 
    tw.Flush(); 
    byte[] bytes = ms.ToArray(); 
    ms.Close(); 

    Response.Clear(); 
    Response.ContentType = "application/force-download"; 
    Response.AddHeader("content-disposition", "attachment; filename=" + string.Format("kaws-structures-{0:yyyy.MM.dd}.csv", DateTime.Today)); 
    Response.BinaryWrite(bytes); 
    Response.End(); 
} 

string EscapeIfNeeded(string s) 
{ 
    if (s.Contains(",")) 
    { 
     return "\"" + s.Replace("\"", "\"\"") + "\""; 
    } 
    else 
    { 
     return s; 
    } 
} 

नीचे एक्सेल के लिए समस्या पैदा होगी। एक्सेल में पहला उद्धरण डेटा का हिस्सा बन जाएगा और इसके परिणामस्वरूप एम्बेडेड कॉमा पर अलग से अलग होगा। जगह खराब है।

tw.Write(Environment.NewLine + string.Format("{0:#.000000}, {1:#.000000}, {2}, {3}, {4}, {5}, {6}, {7}, {8}", s.LATITUDE, s.LONGITUDE, s.CO_SER, EscapeIfNeeded(s.SuperTypeLookup.SHORTDESC), EscapeIfNeeded(s.OrientationLookup.SHORTDESC), s.DISTRICT, s.ROUTE_PREFIX, s.RouteValue, EscapeIfNeeded(s.LOC_DESC))); 
संबंधित मुद्दे