我正在尝试使用操作提供由数据库制成的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返回,结果相同。
任何想法?
谢谢,
卡尔
Update:我也尝试从相同的内容提供XML,并且它也被截断了。它不会在数据上被截断(我认为它可能是其中的EOF字符),但是会在标签中间截断...
我遇到了完全相同的问题。文本文件将始终被截断返回。
我想到这可能是一个“冲洗”问题,的确如此。在操作结束时,没有刷新writer的缓冲区-因为没有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;
}
您为什么使用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");
}
您可能想关闭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();
}
}