代码之家  ›  专栏  ›  技术社区  ›  Jagd Dai

sqlfilestream写入错误?

  •  0
  • Jagd Dai  · 技术社区  · 14 年前

    几个月来,我一直在向一个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();
    
    2 回复  |  直到 14 年前
        1
  •  2
  •   Remus Rusanu    14 年前
    while ((read = objSqlFileStream.Read(b, 0, b.Length)) > 0) {
       Response.BinaryWrite(b);
    }
    

    这写的是整个原件 byte[] 数组 b 忽略了尺寸 read . 令人震惊的是,httpresponse没有签名 .BinaryWrite(byte[], offset, size) …恐怕你得 b.Resize(read); 在你写出来之前。

        2
  •  0
  •   Beth    14 年前

    写后清除字节数组有帮助吗?