【问题标题】:c# web api return with whole file instead of byte arrayc# web api返回整个文件而不是字节数组
【发布时间】:2018-06-11 02:47:10
【问题描述】:

对于我当前的 web api,我将文件返回为 byte[],它通过以下代码工作。

[Route("GetReferenceFile")]
    [HttpPost]
    public HttpResponseMessage GetReferenceFile([FromBody]ReferenceFileMonitorRetrievingRequest request)
    {
        try
        {
            var fileName = request.fileName;
            //get file path
            var filePathWoFileName = _manager.GetReferenceFileForReferenceFileMonitor(request.fileName, request.fileFolderPathWithFileName);
            //convert file into bytes array
            var dataBytes = File.ReadAllBytes(filePathWoFileName + request.fileName);
            //add bytes to memory stream 
            var dataStream = new MemoryStream(dataBytes);
            //send out
            HttpResponseMessage httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK);
            httpResponseMessage.Content = new StreamContent(dataStream);
            httpResponseMessage.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
            httpResponseMessage.Content.Headers.ContentDisposition.FileName = fileName;
            httpResponseMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");

            return httpResponseMessage;
        }
        catch (IOException e)
        {
            logger.Error("Error Message: " + e.Message + " Stack Trace: " + e.StackTrace);
            return Request.CreateResponse(HttpStatusCode.InternalServerError, e);
        }
        catch (Exception ex)
        {
            logger.Error("Error Message: " + ex.Message + " Stack Trace: " + ex.StackTrace);
            return Request.CreateResponse(HttpStatusCode.InternalServerError, ex);
        }

请问有没有其他方法可以将整个文件发送过来,而不是将文件读取为 byte[] 并发送过来?因为我担心读取为 byte[] 可能会稍微改变文件,例如:“Tab”所产生的空间可能不会保持不变。

提前谢谢你。


已编辑:

我使用 System.Text.Encoding.UTF8.GetString(//byte array) 将字节数组转换为字符串并写入文件。这会引起更改原始文件内容的任何担忧吗?谢谢你。

public async Task<string> GetReferenceFile(ReferenceFileRequest referenceFileRequest)
    {
        ConfigurationManager.RefreshSection("appSettings");
        var URL = ConfigurationManager.AppSettings["GetReferenceFile"];
        byte[] refFile = new byte[0];
        try
        {
            Client.DefaultRequestHeaders.Accept.Clear();
            Client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));
            HttpResponseMessage response = await Client.PostAsJsonAsync(URL, referenceFileRequest);

            refFile = await response.Content.ReadAsByteArrayAsync();
            return System.Text.Encoding.UTF8.GetString(refFile); //Convert to string
        }
        catch (Exception ex)
        {
            logData.LogError("Error Message: " + ex.Message + " Stack Trace: " + ex.StackTrace);
            return null;
        }
    }

【问题讨论】:

  • 我看不出以字节读取会如何改变文件,代表制表符的字节和代表空格的字节应该是不同的。另外,据我所知,网络数据包必须先转换为字节才能发送。
  • 谢谢。我检查了它们是不同的。水平制表符为二进制代码:00001001,空格为二进制代码:00100000。

标签: c# file asp.net-web-api


【解决方案1】:

解决您的顾虑:字节是 .NET 可以使用标准 IO 代码读取文件的最低级别。当您读取字节时,您正在读取原始文件数据。它是 EXE、Word 文档还是文本文件都没有关系。当您开始尝试使用错误的编码 在字节和文本之间进行转换时,可能会发生您描述的问题。既然你在这里没有做类似的事情,你应该没有问题。

不过,您可以进行优化。目前,您正在将整个文件读入内存。您可以改为将文件直接通过管道传递给响应。

替换此代码:

var dataBytes = File.ReadAllBytes(filePathWoFileName + request.fileName);
//add bytes to memory stream 
var dataStream = new MemoryStream(dataBytes);
//send out
HttpResponseMessage httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK);
httpResponseMessage.Content = new StreamContent(dataStream);

有了这个:

var dataStream = File.OpenRead(filePathWoFileName + request.fileName);
//send out
HttpResponseMessage httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK);
httpResponseMessage.Content = new StreamContent(dataStream);

【讨论】:

  • 谢谢。您的回复确实帮助我消除了疑惑!我可以请您看一下新编辑的帖子,看看“转换过程”是否会引起任何关注?再次感谢。
  • @Xiaoyu 你真的不应该编辑你的问题来改变你的要求,尤其是在你收到答案之后。回答你的问题:不可能回答。问题来自使用错误的编码类型读取数据。在 UTF8 中,单个日文字符占用 3 个字节。在 ASCII 中,单个字符占用一个字节。如果我将 UTF8 编码的日文文本解释为 ASCII,我自然会得到一个 3 倍长且字符错误的字符串。即使是占用相同字节数的两个字符集也可能非常不同且不兼容。
  • 您应该阅读 this 以了解不同的字符集。
猜你喜欢
  • 2023-04-03
  • 1970-01-01
  • 2021-10-17
  • 2015-01-29
  • 1970-01-01
  • 2016-04-28
  • 1970-01-01
  • 2019-11-27
  • 1970-01-01
相关资源
最近更新 更多