将流保存到asp.net 3.5中的文件的最佳方法?

时间:2009-02-22 05:18:04

标签: c# asp.net resources stream

我有一个Stream对象,其中填充了我正在处理的项目中作为嵌入式资源的XSD文件的内容,如下所示:

using ( Stream xsdStream = assembly.GetManifestResourceStream( xsdFile ) )
{
  // Save the contents of the xsdStream here...
}

在此使用块中,我想在Web上提示用户使用“保存文件”对话框,他们可以选择保存流中包含的此XSD文件。

实现这一目标的最佳方法是什么?我完全迷失了,似乎谷歌没有正确的条款来获得相关的答案。

谢谢!

4 个答案:

答案 0 :(得分:2)

如果您不使用AJAX,则可以使用Response.WriteFile。否则我会使用MemoryStream。这就是我做到的here。对不起,这是在VB.NET中,我还没有转码。请注意,这也允许您通过网络服务器下载文件,即如果您的文件位于没有公共访问权限的应用服务器上。

Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Sql
Imports System.Net
Imports System.IO

Partial Class DownloadFile
Inherits System.Web.UI.Page

Protected Sub page_load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim url As String = Request.QueryString("DownloadUrl")
If url Is Nothing Or url.Length = 0 Then Exit Sub

'Initialize the input stream
Dim req As HttpWebRequest = WebRequest.Create(url)
Dim resp As HttpWebResponse = req.GetResponse()
Dim bufferSize As Integer = 1 

'Initialize the output stream
Response.Clear()
Response.AppendHeader("Content-Disposition:", "attachment; filename=download.zip")
Response.AppendHeader("Content-Length", resp.ContentLength.ToString)
Response.ContentType = "application/download"

'Populate the output stream
Dim ByteBuffer As Byte() = New Byte(bufferSize) {}
Dim ms As MemoryStream = New MemoryStream(ByteBuffer, True)
Dim rs As Stream = req.GetResponse.GetResponseStream()
Dim bytes() As Byte = New Byte(bufferSize) {}
While rs.Read(ByteBuffer, 0, ByteBuffer.Length) > 0
Response.BinaryWrite(ms.ToArray())
Response.Flush()
End While

'Cleanup
Response.End()
ms.Close()
ms.Dispose()
rs.Dispose()
ByteBuffer = Nothing
End Sub
End Class

答案 1 :(得分:1)

您需要设置内容处置:

Response.AddHeader "Content-Disposition","attachment; filename=" & xsdFile

您还需要将Content-Type设置为text / plain,将Content-Length设置为文件的大小。然后你写了文件的内容。

答案 2 :(得分:1)

private void DownloadEmbeddedResource( 
  string resourceName, Assembly resourceAssembly, string downloadFileName )
{
  using ( Stream stream = resourceAssembly.GetManifestResourceStream( resourceName ) )
  {
    if ( stream != null )
    {
      Response.Clear();
      string headerValue = string.Format( "attachment; filename={0}", downloadFileName );
      Response.AppendHeader( "Content-Disposition:", headerValue );
      Response.AppendHeader( "Content-Length", stream.Length.ToString() );
      Response.ContentType = "text/xml";

      var byteBuffer = new Byte[1];

      using ( var memoryStream = new MemoryStream( byteBuffer, true ) )
      {
        while ( stream.Read( byteBuffer, 0, byteBuffer.Length ) > 0 )
        {
          Response.BinaryWrite( memoryStream.ToArray() );
          Response.Flush();
        }
      }

      Response.End();
    }
  }
}

我最终使用了上述方法。感谢您帮助我使用tsilb语法。 JohannesH,如果资源不是来自不同的大会,我会使用你的建议(对不起,我应该在原来的问题中清除它)。

上面的代码有效但我遇到了一个相当奇怪的问题......在方法完成并且下载完成后,页面仍然似乎永远不会恢复生命并且鼠标仍然处于沙漏模式,就像它仍然认为工作正在进行中。关于如何解决问题的任何想法?

再次感谢您的帮助!

答案 3 :(得分:0)

听起来你应该看一下WebResource.axd处理程序。

微软在这个问题上有一个很好的article

修改

似乎tsilb在一分钟左右的时间内击败了我的答案。但是,AssemblyResourceLoader(aka.WebResource.axd)已经实现为您执行此操作并正确执行此操作,并且不要忘记此小狗支持输出缓存。因此,请继续使用它,以免给自己带来麻烦。 ;)