2012-06-21 13 views
17

पर स्ट्रीमवाइटर लेखन मैं इस धारणा के तहत था कि जब आपने स्ट्रीमवाइटर ऑब्जेक्ट में Flush() कहा था तो यह अंतर्निहित धारा को लिखता है, लेकिन स्पष्ट रूप से यह मेरे कोड के मामले में नहीं है।मेमोरीस्ट्रीम

मेरी फ़ाइल में लिखने के बजाय यह कुछ भी नहीं लिखेंगे। कोई विचार जहां मैं गलत जा रहा हूँ?

public FileResult DownloadEntries(int id) 
    { 
     Competition competition = dataService.GetCompetition(id); 
     IQueryable<CompetitionEntry> entries = dataService.GetAllCompetitionEntries().Where(e => e.CompetitionId == competition.CompetitionId); 

     MemoryStream stream = new MemoryStream(); 
     StreamWriter csvWriter = new StreamWriter(stream, Encoding.UTF8); 

     csvWriter.WriteLine("First name,Second name,E-mail address,Preferred contact number,UserId\r\n"); 

     foreach (CompetitionEntry entry in entries) 
     { 
      csvWriter.WriteLine(String.Format("{0},{1},{2},{3},{4}", 
       entry.User.FirstName, 
       entry.User.LastName, 
       entry.User.Email, 
       entry.User.PreferredContactNumber, 
       entry.User.Id)); 
     } 

     csvWriter.Flush(); 

     return File(stream, "text/plain", "CompetitionEntries.csv"); 
    } 
+2

उचित कचरा संग्रहण के लिए बयानों का उपयोग करने में अपने MemoryStream और StreamWriter डालने पर विचार करें। – neontapir

+0

@neontapir मैं अभी तक सफाई के लिए कोड नहीं हूँ लेकिन बाद में होगा। चीयर्स – ediblecode

+0

@neontapir, इस विशेष मामले के लिए गलत टिप्पणी: इससे केवल समस्या अधिक गंभीर/स्पष्ट हो जाएगी ... –

उत्तर

24

मुझे विश्वास है कि आपको Stream.Position = 0 सेट करने की आवश्यकता है। जब आप लिखते हैं, तो यह स्थिति के अंत तक स्थिति को आगे बढ़ाता है। जब आप इसे File() पर पास करते हैं तो यह उस स्थिति से शुरू होता है - अंत में।

मुझे लगता है कि निम्नलिखित काम (इस संकलन करने की कोशिश नहीं की) होगा:

stream.Position = 0; 
return File(stream, "text/plain", "CompetitionEntries.csv"); 

और इस तरह से आप किसी भी नई वस्तुओं बनाने या अंतर्निहित सरणी नकल नहीं कर रहे।

+2

कृपया ध्यान दें कि * * नियंत्रक के कोड में लेखक और स्ट्रीम का निपटान नहीं करना चाहिए। कॉपी-पेस्ट होने पर आपको इसके बारे में अपने कोड में टिप्पणी जोड़ने की आवश्यकता हो सकती है। –

7

आपकी मेमोरीस्ट्रीम अंत में स्थित है। MemoryStream(Byte[], Int32, Int32, Boolean) कन्स्ट्रक्टर का उपयोग करके एक ही बफर पर नई आर/ओ मेमोरी स्ट्रीम बनाने के लिए बेहतर कोड होगा।

सरल आर/छंटनी बफर पर w:

return File(new MemoryStream(stream.GetBuffer(), 0, (int)stream.Length, false); 

नोट::

return File(new MemoryStream(stream.ToArray()); 

आर/ओ आंतरिक बफर कॉपी किए बिना ही धारा आप फ़ाइल के माध्यम से लौट रहे हैं निपटाने के प्रति सावधान रहें (स्ट्रीम)। अन्यथा आपको किसी प्रकार का "ऑब्जेक्ट डिस्प्ले अपवाद" प्राप्त होगा। अर्थात। यदि आप बस मूल स्ट्रीम की स्थिति 0 पर सेट करते हैं और स्ट्रीमवाइटर को उपयोग करने के लिए लपेटते हैं तो आप डिस्प्ले स्ट्रीम को वापस कर पाएंगे।

+0

इसे ठीक से हल किया गया। धन्यवाद – ediblecode

+0

मैंने अपने संपादन के साथ 'उपयोग' का उपयोग करने पर सावधानी बरतनी है। –

+0

दिलचस्प। जैसा कि मैंने नीचे दिखाया है, मैं उपयोग कथन के साथ काम के समान कुछ प्राप्त करने में सक्षम था। – neontapir

2

इस के साथ खेल में, मैं काम करने के लिए निम्नलिखित प्रोटोटाइप मिला:

using System.Web.Mvc; 
using NUnit.Framework; 

namespace StackOverflowSandbox 
{ 
[TestFixture] 
public class FileStreamResultTest 
{ 
    public FileStreamResult DownloadEntries(int id) 
    { 
     // fake data 
     var entries = new[] {new CompetitionEntry { User = new Competitor { FirstName = "Joe", LastName = "Smith", Email = "[email protected]", Id=id.ToString(), PreferredContactNumber = "555-1212"}}}; 

     using (var stream = new MemoryStream()) 
     { 
      using (var csvWriter = new StreamWriter(stream, Encoding.UTF8)) 
      { 
       csvWriter.WriteLine("First name,Second name,E-mail address,Preferred contact number,UserId\r\n"); 

       foreach (CompetitionEntry entry in entries) 
       { 
        csvWriter.WriteLine(String.Format("{0},{1},{2},{3},{4}", 
                 entry.User.FirstName, 
                 entry.User.LastName, 
                 entry.User.Email, 
                 entry.User.PreferredContactNumber, 
                 entry.User.Id)); 
       } 

       csvWriter.Flush(); 
      } 

      return new FileStreamResult(new MemoryStream(stream.ToArray()), "text/plain"); 
     } 
    } 

    [Test] 
    public void CanRenderTest() 
    { 
     var fileStreamResult = DownloadEntries(1); 
     string results; 
     using (var stream = new StreamReader(fileStreamResult.FileStream)) 
     { 
      results = stream.ReadToEnd(); 
     } 
     Assert.IsNotEmpty(results); 
    } 
} 

public class CompetitionEntry 
{ 
    public Competitor User { get; set; } 
} 

public class Competitor 
{ 
    public string FirstName; 
    public string LastName; 
    public string Email; 
    public string PreferredContactNumber; 
    public string Id; 
} 
} 
संबंधित मुद्दे