asp.net mvc 服务 txt 被截断

发布于 2024-08-15 17:38:32 字数 2046 浏览 4 评论 0原文

我正在尝试使用操作提供从数据库生成的 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。在从 ATxt 返回之前,我还尝试转换为 byte[] 并获得相同的结果。

有什么想法吗?

谢谢,

Carles

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

I'm trying to serve a txt file made from the database using an action. The action is the following:

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

and the CatalegATxt class is:

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

it just writes the file lines based on the stuff I got from the database. But when I look at the file it looks truncated. The file is about 8Mb. I also tried converting to byte[] before returning from ATxt with the same result.

Any idea?

Thanks,

Carles

Update: I also tried to serve XML from the same content and it also gets truncated. It doesn't get truncated on the data (I thought it might have been an EOF character in it) but it truncates in the middle of a label...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦亿 2024-08-22 17:38:32

我遇到了完全相同的问题。文本文件将始终以被截断的形式返回。

我突然想到这可能是一个“冲洗”问题,确实如此。写入器的缓冲区在操作结束时尚未刷新 - 因为没有 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;
}

I was having the exact same problem. The text file would always be returned as truncated.

It crossed my mind that it might be a "flushing" problem, and indeed it was. The writer's buffer hasn't been flushed at the end of the operation - since there's no using block, or the Close() call - which would flush automatically.

You need to call:

streamWriter.Flush();

before MVC takes over the stream.

Here's how your method should look like:

 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;
}
美人骨 2024-08-22 17:38:32

为什么要使用 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");
}

Why are you using an ActionResult?

ASP.NET MVC 1 has a FileStreamResult for just what you are doing. It expects a Stream object, and returns it.

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

Should work fine for what you want to do. No need to do any conversions.

In your case, just change your method to this:

public FileStreamResult ATxt()
{
    var articulos = _articulosService.ObteTotsArticles();
    return new FileStreamResult(CatalegATxt.ATxt(articulos), "text/plain");
}
°如果伤别离去 2024-08-22 17:38:32

您可能想要关闭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();
    }
}

You probably want to close the MemoryStream. It could be getting truncated because it expects more data still. Or to make things even simpler, try something like this:

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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文