如何正确地提供PDF文件

时间:2010-01-30 21:08:17

标签: c# asp.net pdf 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);

这不起作用(例如浏览器的PDF插件会抱怨文件已损坏)。

所以我尝试了Unicode方法:

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

也没用。

我错过了什么?

3 个答案:

答案 0 :(得分:7)

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

应将字节写入Response实例的the 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;
    }
}

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

LoadStreamToStream(fileStream, Response.OutputStream);

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

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

答案 1 :(得分:2)

您可能还需要通过执行以下操作来设置ContentType:

Response.ContentType = "application/octet-stream";

答案 2 :(得分:0)

Peter Lillevold's回答的基础上,我为上述功能做了一些扩展方法。

public static void WriteTo(this 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;
    }
}

public static void WriteToFromFile(this Stream outputStream, string inputFile)
{
    using (var inputStream = new FileStream(inputFile, FileMode.Open, FileAccess.Read))
    {
        inputStream.WriteTo(outputStream);
        inputStream.Close();
    }
}