SqlFileStream Написать ошибку? - PullRequest
       6

SqlFileStream Написать ошибку?

0 голосов
/ 20 августа 2010

Я уже несколько месяцев пишу и читаю PDF-файлы в SQL Server 2008 FileStream без каких-либо серьезных проблем (кроме утомительных прав пользователей). Вчера я попросил пользователя сообщить, что некоторые его PDF-файлы были повреждены после записи в FileStream. Итак, я выполнил некоторую отладку и обнаружил проблему, но, похоже, это ошибка библиотек SqlFileStream, которые записывают файл в FileStream.

Вот мой код, который пишет в 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();

Из своей отладки я определил, что последнее чтение итерации из потока имеет значение чтения, равное 1253, что означает, что последнее чтение потока имеет данные в байтовом массиве с индексом от 0 до 1252, , и это правильный . Все до и после 1253 года взято из предыдущего чтения.

Итак, я понимаю, что sqlFS.Write (b, 0, 1253) запишет все, начиная с индекса 0 до 1252 байтового массива, в SqlFileStream. Однако фактически он записывает все в байтовом массиве в SqlFileStream. Я подтвердил это, вытащив PDF-файл обратно из базы данных, и, хотя я не могу просмотреть его в обычном режиме, поскольку он теперь поврежден, я все равно могу открыть его в текстовом редакторе и посмотреть на конец строки, который не отображается. t принадлежат там (все данные, которые были в позиции 1253 и после).

Я что-то здесь не так делаю, или метод SqlFileStream Write имеет ошибку, как мне кажется?

Странно то, что я загрузил довольно много других PDF-файлов, текстовых файлов и изображений, и я никогда не видел этой проблемы. Я понятия не имею, почему это происходит с некоторыми PDF, а не с другими ...

EDIT: Вот код для моего метода чтения. Ошибка также может быть здесь (спасибо Ремусу за то, что указал на это!).

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 ]

2 голосов
/ 20 августа 2010
while ((read = objSqlFileStream.Read(b, 0, b.Length)) > 0) {
   Response.BinaryWrite(b);
}

Это записывает весь оригинальный byte[] массив b и игнорирует размер read. Я ужасно сожалею, что HttpResponse не имеет подписи .BinaryWrite(byte[], offset, size) ... Боюсь, вам придется b.Resize(read);, прежде чем вы ее напишите.

0 голосов
/ 20 августа 2010

Помогает ли очистить массив байтов после записи?

...