3

我正在尝试使用操作提供从数据库制作的 txt 文件。动作如下:

public ActionResult ATxt()
{
    var articulos = _articulosService.ObteTotsArticles();
    return File(CatalegATxt.ATxt(articulos), "text/plain");
}

CatalegATxt 类是:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using WebDibaelsaMVC.DTOs.Busqueda;

namespace WebDibaelsaMVC.TxtLib
{
    public static class CatalegATxt
    {
         public static Stream ATxt(IEnumerable<ArticuloBusquedaDTO> articles)
         {
            var stream = new MemoryStream();
            var streamWriter = new StreamWriter(stream, Encoding.UTF8);
            foreach (ArticuloBusquedaDTO article in articles)
            {
                streamWriter.WriteLine(article.ToStringFix());
            }
            stream.Seek(0, SeekOrigin.Begin);
            return stream;
        }

        public static string ToStringFix(this ArticuloBusquedaDTO article)
        {
            string result = "";
            result += article.CodigoArticulo.PadRight(10, ' ').Substring(0, 10);
            result += article.EAN.Trim().PadLeft(13, '0').Substring(0, 13);
            result += article.NombreArticulo.PadRight(100, ' ').Substring(0, 100);
            result += article.Marca.PadRight(100, ' ').Substring(0, 100);
            result += article.Familia.PadRight(50, ' ').Substring(0, 50);
            result += article.PrecioCesion.ToStringFix();
            result += article.PVP.ToStringFix();
            return result;
        }

        private static string ToStringFix(this double numero)
        {
            var num = (int)Math.Round(numero * 100, 0);
            string result = num.ToString().PadLeft(10, '0');
            return result;
        }
    }
}

它只是根据我从数据库中获得的内容编写文件行。但是当我查看文件时,它看起来被截断了。该文件约为8Mb。byte[]在从 ATxt 返回之前,我也尝试转换为相同的结果。

任何的想法?

谢谢,

卡尔斯

更新:我还尝试从相同的内容中提供 XML,但它也被截断了。它不会在数据上被截断(我认为它可能是一个 EOF 字符),但它在标签中间被截断......

4

3 回答 3

5

我遇到了完全相同的问题。文本文件将始终作为截断返回。

我突然想到这可能是一个“冲洗”问题,确实如此。在操作结束时尚未刷新写入器的缓冲区 - 因为没有 using 块或 Close() 调用 - 这将自动刷新。

您需要致电:

streamWriter.Flush();

在 MVC 接管流之前。

以下是您的方法的外观:

 public static Stream ATxt(IEnumerable<ArticuloBusquedaDTO> articles)
 {
    var stream = new MemoryStream();
    var streamWriter = new StreamWriter(stream, Encoding.UTF8);
    foreach (ArticuloBusquedaDTO article in articles)
    {
        streamWriter.WriteLine(article.ToStringFix());
    }
    // Flush the stream writer buffer
    streamWriter.Flush();
    stream.Seek(0, SeekOrigin.Begin);
    return stream;
}
于 2009-12-31T01:17:58.690 回答
3

为什么要使用 ActionResult?

ASP.NET MVC 1 有一个 FileStreamResult 用于您正在做的事情。它需要一个 Stream 对象,并返回它。

public FileStreamResult Test()
{
  return new FileStreamResult(myMemoryStream, "text/plain");
}

应该可以很好地完成您想做的事情。无需进行任何转换。

在您的情况下,只需将您的方法更改为:

public FileStreamResult ATxt()
{
    var articulos = _articulosService.ObteTotsArticles();
    return new FileStreamResult(CatalegATxt.ATxt(articulos), "text/plain");
}
于 2009-12-24T13:34:12.883 回答
0

您可能想要关闭MemoryStream. 它可能会被截断,因为它仍然需要更多数据。或者为了让事情变得更简单,试试这样的事情:

public static byte[] ATxt(IEnumerable<ArticuloBusquedaDTO> articles)
{
   using(var stream = new MemoryStream())
   {
        var streamWriter = new StreamWriter(stream, Encoding.UTF8);
        foreach (ArticuloBusquedaDTO article in articles)
        {
            streamWriter.WriteLine(article.ToStringFix());
        }

        return stream.ToArray();
    }
}
于 2009-12-24T13:00:50.443 回答