C#实现以文件流的形式返回本地文件或远程文件路径

 更新时间:2025年08月21日 15:49:43   作者:VipSoft  
FileStream和FileInfo只能处理本地文件路径,无法直接处理HTTP URL,所以下面小编就来和大家详细介绍一下C#如何实现以文件流的形式返回本地文件或远程文件路径吧

FileStreamFileInfo只能处理本地文件路径,无法直接处理HTTP URL。以下是几种实现远程PDF返回给前端的解决方案:

方案1:使用HttpClient下载远程文件(推荐)

[HttpGet]
public async Task<HttpResponseMessage> GetReportFile()
{  
    try
    {
        string orderNo = HttpContext.Current.Request.QueryString["orderNo"];
        string filePath = "D:\\1.pdf";
        
        if(!string.IsNullOrEmpty(orderNo))
        {            
            filePath = "http://www.a.com/1.pdf";
            
            // 使用HttpClient下载远程文件
            using (var httpClient = new HttpClient())
            {
                // 设置超时时间
                httpClient.Timeout = TimeSpan.FromSeconds(30);
                
                // 下载文件内容
                var response = await httpClient.GetAsync(filePath);
                response.EnsureSuccessStatusCode();
                
                var content = await response.Content.ReadAsByteArrayAsync();
                
                // 创建返回结果
                var result = new HttpResponseMessage(HttpStatusCode.OK);
                result.Content = new ByteArrayContent(content);
                result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
                result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("inline")
                {
                    FileName = "document.pdf"
                };
                
                return result;
            }
        }
        else
        {
            // 处理本地文件
            FileInfo foundFileInfo = new FileInfo(filePath);
            FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            
            var result = new HttpResponseMessage(HttpStatusCode.OK);
            result.Content = new StreamContent(fs);
            result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
            result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("inline")
            {
                FileName = foundFileInfo.Name
            };
            
            return result;
        }
    }
    catch (Exception ex)
    {
        logger.Error(ex, ex.Message);
        return new HttpResponseMessage(HttpStatusCode.BadRequest);
    }
}

方案2:流式传输(节省内存)【推荐】

[HttpGet]
public async Task<HttpResponseMessage> GetReportFile()
{  
    try
    {
        string orderNo = HttpContext.Current.Request.QueryString["orderNo"];
        string filePath = "D:\\1.pdf";
        
        if(!string.IsNullOrEmpty(orderNo))
        {            
            filePath = "http://www.a.com/1.pdf";
            
            using (var httpClient = new HttpClient())
            {
                httpClient.Timeout = TimeSpan.FromSeconds(30);
                
                // 流式下载
                var response = await httpClient.GetAsync(filePath, HttpCompletionOption.ResponseHeadersRead);
                response.EnsureSuccessStatusCode();
                
                var stream = await response.Content.ReadAsStreamAsync();
                
                var result = new HttpResponseMessage(HttpStatusCode.OK);
                result.Content = new StreamContent(stream);
                result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
                result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("inline")
                {
                    FileName = "document.pdf"
                };
                
                return result;
            }
        }
        else
        {
            // 本地文件处理...
        }
    }
    catch (Exception ex)
    {
        logger.Error(ex, ex.Message);
        return new HttpResponseMessage(HttpStatusCode.BadRequest);
    }
}

方案3:添加缓存和错误处理

[HttpGet]
public async Task<HttpResponseMessage> GetReportFile()
{  
    try
    {
        string orderNo = HttpContext.Current.Request.QueryString["orderNo"];
        string filePath = "D:\\1.pdf";
        
        if(!string.IsNullOrEmpty(orderNo))
        {            
            filePath = "http://www.a.com/1.pdf";
            
            using (var httpClient = new HttpClient())
            {
                // 添加User-Agent头,有些服务器需要
                httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0");
                httpClient.Timeout = TimeSpan.FromSeconds(30);
                
                // 先获取头部信息检查文件是否存在
                var headResponse = await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, filePath));
                
                if (!headResponse.IsSuccessStatusCode)
                {
                    return new HttpResponseMessage(HttpStatusCode.NotFound)
                    {
                        Content = new StringContent("远程文件未找到")
                    };
                }
                
                // 获取文件名(从Content-Disposition或URL中提取)
                string fileName = "document.pdf";
                if (headResponse.Content.Headers.ContentDisposition != null)
                {
                    fileName = headResponse.Content.Headers.ContentDisposition.FileName ?? fileName;
                }
                
                // 下载文件
                var getResponse = await httpClient.GetAsync(filePath, HttpCompletionOption.ResponseHeadersRead);
                getResponse.EnsureSuccessStatusCode();
                
                var result = new HttpResponseMessage(HttpStatusCode.OK);
                result.Content = new StreamContent(await getResponse.Content.ReadAsStreamAsync());
                result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
                result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("inline")
                {
                    FileName = fileName
                };
                
                // 添加缓存头(可选)
                result.Headers.CacheControl = new CacheControlHeaderValue()
                {
                    MaxAge = TimeSpan.FromHours(1)
                };
                
                return result;
            }
        }
        else
        {
            // 本地文件处理...
        }
    }
    catch (HttpRequestException httpEx)
    {
        logger.Error(httpEx, "网络请求错误");
        return new HttpResponseMessage(HttpStatusCode.BadGateway);
    }
    catch (TaskCanceledException timeoutEx)
    {
        logger.Error(timeoutEx, "请求超时");
        return new HttpResponseMessage(HttpStatusCode.RequestTimeout);
    }
    catch (Exception ex)
    {
        logger.Error(ex, ex.Message);
        return new HttpResponseMessage(HttpStatusCode.InternalServerError);
    }
}

重要注意事项

  • 异步方法:将方法改为async Task<HttpResponseMessage>以支持异步操作
  • 资源释放:确保正确释放HttpClient和流资源
  • 超时处理:为远程请求设置合理的超时时间
  • 错误处理:添加针对网络请求的特定错误处理
  • 内存考虑:对于大文件,使用流式传输避免内存溢出

推荐使用方案2的流式传输,因为它内存效率更高,特别适合处理大文件。

到此这篇关于C#实现以文件流的形式返回本地文件或远程文件路径的文章就介绍到这了,更多相关C#文件流返回文件路径内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#实现拆分合并Word表格中的单元格

    C#实现拆分合并Word表格中的单元格

    我们在使用Word制作表格时,由于表格较为复杂,只是简单的插入行、列并不能满足我们的需要。要做一个完整的表格,很多时候需要将单元格进行拆分或者合并。本文将详细为您介绍在Word表格中拆分或合并单元格的思路及方法,希望对大家有所帮助
    2022-12-12
  • C#使用Sleep(Int32)方法实现动态显示时间

    C#使用Sleep(Int32)方法实现动态显示时间

    这篇文章主要为大家详细介绍了C#如何使用Sleep(Int32)方法实现动态显示时间,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考下
    2024-01-01
  • 使用C#实现MD5加密的方法详解

    使用C#实现MD5加密的方法详解

    在软件开发中,加密是保护数据安全的重要手段之一,MD5(Message Digest Algorithm 5)是一种常用的哈希算法,用于生成数据的摘要或哈希值,本文介绍了如何使用C#语言实现MD5加密的方法,涵盖了基本的使用方式和扩展方法封装,需要的朋友可以参考下
    2024-08-08
  • C#高性能动态获取对象属性值的步骤

    C#高性能动态获取对象属性值的步骤

    这篇文章主要介绍了C#高性能动态获取对象属性值的步骤,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下
    2020-12-12
  • Unity实现简单虚拟摇杆

    Unity实现简单虚拟摇杆

    这篇文章主要为大家详细介绍了Unity实现简单虚拟摇杆,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • c#通过xpath读取xml示例

    c#通过xpath读取xml示例

    这篇文章主要介绍了c#通过xpath读取xml示例,需要的朋友可以参考下
    2014-04-04
  • 详解C#App.config和Web.config加密

    详解C#App.config和Web.config加密

    本篇文章给大家分享了C#App.config和Web.config加密的相关知识点以及具体代码步骤,有兴趣的朋友参考学习下。
    2018-05-05
  • C#实现简易多人聊天室

    C#实现简易多人聊天室

    这篇文章主要为大家详细介绍了C#实现简易多人聊天室,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • C# Datatable筛选过滤的四种方法实现

    C# Datatable筛选过滤的四种方法实现

    本文主要介绍了C# Datatable筛选过滤的四种方法实现,包括Select、LINQ、DataView、动态条件,各方法在排序、性能及适用场景上有不同特点,感兴趣的可以了解一下
    2025-06-06
  • c# 从IE浏览器获取当前页面的内容

    c# 从IE浏览器获取当前页面的内容

    从IE浏览器获取当前页面内容可能有多种方式,今天我所介绍的是其中一种方法。基本原理:当鼠标点击当前IE页面时,获取鼠标的坐标位置,根据鼠标位置获取当前页面的句柄,然后根据句柄,调用win32的东西进而获取页面内容。感兴趣的朋友可以参考下本文
    2021-06-06

最新评论