我将图像存储在我的数据库中的FILESTREAM中,我试图找出将图像恢复到Web浏览器的最佳解决方案。
如果我自己管理文件系统上的文件,那么最快的方法就是:
Response.TransmitFile(pathToFile);
在将文件传回客户端之前(根据我的理解),这不会将文件加载到内存中,因此非常快速。
我目前正在使用Linq to SQL来获取FILESTREAM。这提供了FILESTREAM作为二进制对象。
到目前为止,这种做法非常丑陋:
Response.WriteBinary(fileStreamBinary.ToArray());
我是否会更好地避免使用Linq to SQL并直接做事?
我开始想知道为什么我首先对FILESTREAM感到困扰并且不仅仅是坚持自己管理文件。我确定没有使用“乐队”这个词就有理由!
答案 0 :(得分:1)
怎么样?
byte[] buffer = new byte[bufferSize];
int nBytes;
while((nBytes = fileStreamBinary.Read(buffer, 0, bufferSize) != 0)
{
Response.OutputStream.Write(buffer, 0, nBytes);
}
这样你永远不会将整个流加载到内存
答案 1 :(得分:1)
在将文件传回之前,不会将文件加载到内存中 客户(据我的理解),因此很好,很快。
正确,但请记住将Response.BufferOutput
设置为false,默认值为true。
我是否会更好地避免使用Linq to SQL并直接做事?
如果您不想先将整个二进制内容加载到内存中,那么是。这里是an example用于从数据库传输二进制数据(以及启用可恢复的下载功能)。
我开始想知道为什么我在第一次打扰FILESTREAM 地方,并不只是坚持自己管理文件
主要优点是数据完整性,具有事务支持和包含在数据库备份中,因此您不必担心数据库备份和文件系统备份之间的差异。缺点一直是性能,这是整个文件流功能试图克服的。虽然根据this document它们平均小于1mb,但实际上存储在数据库中的速度比在文件系统中存储的速度快。
在Sql Server 2012中,有一个名为FileTables的新功能,它基于FileStream支持。基本上它就像文件系统目录的数据库视图一样,添加到该目录的文件会自动添加到数据库FileTable(是一个固定的模式表,它包含文件的Filestream二进制列,您可以从其他表链接到)。这样您就可以检索文件的路径,该路径可以提供给Response.TransmitFile(...)
函数,但仍然可以从sql文件流支持中受益。
答案 2 :(得分:0)
基本上与托马斯提出的想法相同,但更加冗长。 应该关闭缓冲并定期提交/刷新数据,以避免在将所有传入数据发送到客户端之前缓冲它们。
我正在使用类似的代码从数据库中的Blob流式传输数据(在本例中为Pdf:s) - > WCF服务(流媒体) - > 客户端(浏览器)
对于较小的项目,这可能不是最佳方法,但对于传输来自某种流的内容非常有用。
Response.Clear();
Response.ContentType = "application/pdf";
Response.Buffer = false;
var buffer = new byte[BufferSize];
int bytesRead;
while ((bytesRead = inputStream.Read(buffer, 0, BufferSize)) != 0)
{
if (!Response.IsClientConnected)
break;
Response.OutputStream.Write(buffer, 0, bytesRead);
Response.Flush();
}