Я уже несколько месяцев пишу и читаю 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();