ejemplo crear array archivo c# .net stream memorystream

c# - crear - StreamWriter escribiendo en MemoryStream



memorystream to stream c# (3)

Al jugar con esto, tengo el siguiente prototipo para trabajar:

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; } }

Tenía la impresión de que cuando llamaste a Flush() en un objeto StreamWriter escribe en la transmisión subyacente, pero aparentemente este no es el caso con mi código.

En lugar de escribir en mi archivo, simplemente no escribirá nada. ¿Alguna idea de dónde me estoy equivocando?

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"); }


Creo que debes establecer Stream.Position = 0 . Cuando escribe, avanza la posición hasta el final de la secuencia. Cuando lo pasa a File() comienza desde la posición en la que se encuentra - el final.

Creo que lo siguiente funcionará (no intenté compilar esto):

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

Y de esta forma no está creando ningún objeto nuevo ni copiando el conjunto subyacente.


Su MemoryStream está posicionado al final. Un mejor código sería crear una nueva secuencia de memoria R / o en el mismo búfer utilizando el constructor MemoryStream (Byte [], Int32, Int32, Boolean) .

Simplest r / w en buffer recortado:

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

R / o sin copiar el búfer interno:

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

Nota: tenga cuidado de no desechar el flujo que está devolviendo a través de File (Stream). De lo contrario, obtendrás "ObjectDisposedException" de algún tipo. Es decir, si simplemente establece la posición de la transmisión original en 0 y ajusta StreamWriter en el uso, obtendrá la devolución de la transmisión eliminada.