几个月来,我一直在向一个SQL Server 2008文件流编写和读取PDF,但没有出现任何重大问题(除了冗长的用户权限)。昨天我让一个用户通知我,他们的一些PDF文件在写入到文件流之后被损坏了。因此,我做了一些调试,发现了问题,但似乎是SQLFILESTREAM库的一个错误,它将文件写入了该文件流。
这是我写到文件流的代码:
// Byte array representing the FileStream
byte[] fsBytes = (byte[])obj;
SqlFileStream sqlFS = new SqlFileStream(path, fsBytes, FileAccess.Write);
byte[] b = new byte[4096];
int read;
stream.Seek(0, SeekOrigin.Begin);
while ((read = stream.Read(b, 0, b.Length)) > 0) {
sqlFS.Write(b, 0, read);
}
sqlFS.Close();
从我的调试中,我确定从流中读取的最后一次迭代的读取值等于1253,这意味着最后一次读取的流在索引0到1252的字节数组中有数据,
这是正确的
. 1253年前后的一切都是从上一本书开始的。
所以,我的理解是
sqlfs.write(b,0,1253)
将字节数组的索引0到1252的所有内容写入sqlfilestream。然而,它实际上是在写
一切
在sqlfilestream的字节数组中。我已经通过将PDF从数据库中拉出来验证了这一点,即使我无法正常查看它,因为它现在已经损坏了,我仍然可以在文本编辑器中打开它,并在它的末尾查看不属于那里的garbal(所有在1253及之后的数据)。
我在这里做了一些错误的事情,或者sqlfilestream写方法有我认为有缺陷吗?
奇怪的是,我已经上传了相当多的其他PDF和文本文件以及图片,而且我从未见过这个问题。我不知道为什么有些PDF文件会出现这种情况,而其他文件则不会出现。
编辑:
这是我的读取方法的代码。bug也可能在这里(感谢Remus指出这一点!).
SqlFileStream objSqlFileStream = new SqlFileStream(path, objContext, FileAccess.Read);
objSqlFileStream.Seek(0, SeekOrigin.Begin);
b = new byte[4096];
int read;
while ((read = objSqlFileStream.Read(b, 0, b.Length)) > 0) {
Response.BinaryWrite(b);
}
objSqlFileStream.Close();
编辑2(固定代码):
SqlFileStream objSqlFileStream = new SqlFileStream(path, objContext, FileAccess.Read);
objSqlFileStream.Seek(0, SeekOrigin.Begin);
b = new byte[4096];
int read;
while ((read = objSqlFileStream.Read(b, 0, b.Length)) > 0) {
if (read < 4096) {
byte[] b2 = new byte[read];
System.Buffer.BlockCopy(b, 0, b2, 0, read);
Response.BinaryWrite(b2);
}
else
Response.BinaryWrite(b);
}
objSqlFileStream.Close();