开发者

SqlFileStream Write bug?

开发者 https://www.devze.com 2023-01-12 05:32 出处:网络
I\'ve been writing and reading PDF\'s to a SQL Server 2008 FileStream for a few months now without any major problems (apart from tedious user permissions). Yesterday I had a user inform me that some

I've been writing and reading PDF's to a SQL Server 2008 FileStream for a few months now without any major problems (apart from tedious user permissions). Yesterday I had a user inform me that some of their PDF's were being corrupted after being written into the FileStream. So, I did some debugging and I found the problem, but it appears to be a bug with the SqlFileStream libraries that write the file to the FileStream.

Here is my code that writes to the FileStream:

// 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();

From my debugging, I determined that the last iteration reading from the stream has a read value equal to 1253, which means that the last stream read has data in the byte array from index 0 to 1252, and this is correc开发者_如何学运维t. Everything at and after 1253 is from the previous read.

So, my understanding is that sqlFS.Write(b, 0, 1253) will write everything from index 0 to 1252 of the byte array into the SqlFileStream. However, it is actually writing everything in the byte array to the SqlFileStream. I have verified this by pulling the PDF back out of the database, and even though I can't view it normally since its now corrupted, I can still open it in a text editor and view the garbal at the end of it that doesn't belong there (all of the data that was at position 1253 and after).

I am doing something wrong here, or does the SqlFileStream Write method have a bug like I think it does?

What is odd is that I've uploaded quite a few other PDF's and text files and images and I've never seen this problem. I have no idea why it is occurring with some PDF's and not others...

EDIT: Here is the code for my read method. The bug may be here as well (thanks to Remus for pointing this out!).

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();

EDIT #2 (fixed code):

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();


while ((read = objSqlFileStream.Read(b, 0, b.Length)) > 0) {
   Response.BinaryWrite(b);
}

This writes the entire original byte[] array b and ignores the size read. IS appaling that HttpResponse has no signature .BinaryWrite(byte[], offset, size)... I'm afraid you'll have to b.Resize(read); before you write it out.


Does it help to clear out the byte array after the write?

0

精彩评论

暂无评论...
验证码 换一张
取 消