Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

379
Visualizações
MemoryStream.ToArray() return empty array if StreamWriter is not disposed

I'm trying to get array of bytes from my model to put it in the file. I have a method as such:

        public static byte[] GetByteArray(List<MyModel> models)
    {
        using var ms = new MemoryStream();
        using var sw = new StreamWriter(ms);

        foreach (var model in models)
        {
            sw.Write(model.Id + "," + model.Name);
            sw.WriteLine();
        }

        sw.Dispose();
        return ms.ToArray();
    }

This method works fine, but as may think I don't need to dispose StreamWriter manually, cause I have a using statement. I thought as well, but when I remove sw.Dispose(); the ms.ToArray(); returns an empty array. Can someone explain this behavior to me?

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

You have the line:

using var sw = new StreamWriter(ms);

This only disposes the StreamWriter at the end of the method. However you're calling ms.ToArray() before the end of the method. This means that you're calling ms.ToArray() before the StreamWriter is disposed.

However, the StreamWriter is buffering some data internally, and only flushes this out to the MemoryStream when it is disposed. You therefore need to make sure you dispose the StreamWriter before calling ms.ToArray().

It's probably clearer to use the older using syntax, which is explicit about when the disposal happens:

public static byte[] GetByteArray(List<MyModel> models)
{
    using var ms = new MemoryStream();
    using (var sw = new StreamWriter(ms))
    {
        foreach (var model in models)
        {
            sw.Write(model.Id + "," + model.Name);
            sw.WriteLine();
        }
    }

    return ms.ToArray();
}
over 4 years ago · Santiago Trujillo Relatório

0

The dispose does part of the job. It flushes the writer. Use Flush() to flush it manually.

public static byte[] GetByteArray(List<MyModel> models)
{
    var ms = new MemoryStream();
    using var sw = new StreamWriter(ms);

    foreach (var model in models)
    {
        sw.Write(model.Id + "," + model.Name);
        sw.WriteLine();
    }

    // flush the writer, to make sure it is written to the stream.
    sw.Flush();
    return ms.ToArray();
}

You don't need to dispose the memory stream, because the StreamWriter takes ownership.

I don't like the construct that the streamwriter takes ownage of the memory stream. This is probably because there the streamwriter can also be used directly on a file. A constructor which has a file path as parameter. (so no stream parameter is needed)

StreamWriter leaveOpen constructor

over 4 years ago · Santiago Trujillo Relatório

0

If you writing List<MyModel> items as strings, you can simplify conversion by:

public static byte[] GetByteArray(List<MyModel> models) =>
    Encoding.UTF8.GetBytes(string.Join(Environment.NewLine, 
                                       models.Select(model => $"{model.Id},{model.Name}")));

Or use third-party serializers, such from Newtonsoft.Json (example from here):

public static byte[] Serialize<T>(this T source)
{
    var asString = JsonConvert.SerializeObject(source, SerializerSettings);
    return Encoding.Unicode.GetBytes(asString);
}

public static T Deserialize<T>(this byte[] source)
{
    var asString = Encoding.Unicode.GetString(source);
    return JsonConvert.DeserializeObject<T>(asString);
}
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda