如何正确地提供PDF文件

Ang*_*ker 3 c# pdf asp.net encoding

我使用的是.NET 3.5 ASP.NET.目前,我的网站以下列方式提供PDF文件:

context.Response.WriteFile(@"c:\blah\blah.pdf");

这非常有效.但是,我想通过这种context.Response.Write(char [], int, int)方法提供服务.

所以我尝试通过发送文件

byte [] byteContent = File.ReadAllBytes(ReportPath);
ASCIIEncoding encoding = new ASCIIEncoding();
char[] charContent = encoding.GetChars(byteContent);
context.Response.Write(charContent, 0, charContent.Length);
Run Code Online (Sandbox Code Playgroud)

这没用(例如浏览器的PDF插件抱怨文件已损坏).

所以我尝试了Unicode方法:

byte [] byteContent = File.ReadAllBytes(ReportPath);
UnicodeEncoding encoding = new UnicodeEncoding();
char[] charContent = encoding.GetChars(byteContent);
context.Response.Write(charContent, 0, charContent.Length);
Run Code Online (Sandbox Code Playgroud)

这也没用.

我错过了什么?

Pet*_*old 7

您不应该将字节转换为字符,这就是它变为"损坏"的原因.即使ASCII字符以字节存储,实际的ASCII字符集也限制为7位.因此,使用ASCIIEncoding转换字节流将有效地从每个字节中删除第8位.

应将字节写入Response实例的OutputStream流.

而不是从文件中预先加载所有可能消耗大量内存的字节,从流中读取块中的文件是一种更好的方法.以下是如何从一个流中读取然后写入另一个流的示例:

void LoadStreamToStream(Stream inputStream, Stream outputStream)
{
    const int bufferSize = 64 * 1024;
    var buffer = new byte[bufferSize];

    while (true)
    {
        var bytesRead = inputStream.Read(buffer, 0, bufferSize);
        if (bytesRead > 0)
        {
            outputStream.Write(buffer, 0, bytesRead);
        }
        if ((bytesRead == 0) || (bytesRead < bufferSize))
            break;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用此方法将文件的内容直接加载到Response.OutputStream

LoadStreamToStream(fileStream, Response.OutputStream);
Run Code Online (Sandbox Code Playgroud)

更好的是,这是一个打开文件并将其内容加载到流的方法:

void LoadFileToStream(string inputFile, Stream outputStream)
{
    using (var streamInput = new FileStream(inputFile, FileMode.Open, FileAccess.Read))
    {
        LoadStreamToStream(streamInput, outputStream);
        streamInput.Close();
    }
}
Run Code Online (Sandbox Code Playgroud)