我正在使用.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);
也没用。
我错过了什么?
答案 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();
}
}