Я сохраняю файлы в базе данных SQL Server 2008 (Express) с помощью FILESTREAM, проблема в том, что некоторые файлы, похоже, повреждаются в процессе.Некоторые файлы, поврежденные SQL Server FileStream
Например, если я сохраняю слово или документ excel в одном из новых форматов (docx или xslx), то при попытке открыть файл я получаю сообщение об ошибке, сообщающее, что данные повреждены и мне хотелось бы сложить слова/excel, чтобы попытаться восстановить его. Если я нажму «да», он сможет «восстановить» данные и открыть файл в режиме совместимости.
Однако, если я сначала заархивирую файл, а затем извлекая содержимое, я могу открыть файл без проблем. Странно Если я сохраню mp3-файл в базе данных, тогда у меня есть обратная проблема, я могу открыть файл без проблем, но если бы я сохранил zipped-версию mp3, я даже не смог бы извлечь содержимое этого почтового индекса. Когда я попытался сохранить файл в формате pdf или Power Point, я столкнулся с аналогичными проблемами (pdf, который я мог прочитать только в том случае, если сначала заархивировал его, а ppt я вообще не смог прочитать).
Обновление: вот мой код, который я использую для записи в базу данных и читать
Для записи в базу данных:
SQL = "SELECT Attachment.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() FROM Activity " +
"WHERE RowID = CAST(@RowID as uniqueidentifier)";
transaction = connection.BeginTransaction();
command.Transaction = transaction;
command.CommandText = SQL;
command.Parameters.Clear();
command.Parameters.Add(rowIDParam);
SqlDataReader readerFS = null;
readerFS= command.ExecuteReader();
string path = (string)readerFS[0].ToString();
byte[] context = (byte[])readerFS[1];
int length = context.Length;
SqlFileStream targetStream = new SqlFileStream(path, context, FileAccess.Write);
int blockSize = 1024 * 512; //half a megabyte
byte[] buffer = new byte[blockSize];
int bytesRead = sourceStream.Read(buffer, 0, buffer.Length);
while (bytesRead > 0)
{
targetStream.Write(buffer, 0, bytesRead);
bytesRead = sourceStream.Read(buffer, 0, buffer.Length);
}
targetStream.Close();
sourceStream.Close();
readerFS.Close();
transaction.Commit();
И читать:
SqlConnection connection = null;
SqlTransaction transaction = null;
try
{
connection = getConnection();
connection.Open();
transaction = connection.BeginTransaction();
SQL = "SELECT Attachment.PathName(), + GET_FILESTREAM_TRANSACTION_CONTEXT() FROM Activity"
+ " WHERE ActivityID = @ActivityID";
SqlCommand command = new SqlCommand(SQL, connection);
command.Transaction = transaction;
command.Parameters.Add(new SqlParameter("ActivityID", activity.ActivityID));
SqlDataReader reader = command.ExecuteReader();
string path = (string)reader[0];
byte[] context = (byte[])reader[1];
int length = context.Length;
reader.Close();
SqlFileStream sourceStream = new SqlFileStream(path, context, FileAccess.Read);
int blockSize = 1024 * 512; //half a megabyte
byte[] buffer = new byte[blockSize];
List<byte> attachmentBytes = new List<byte>();
int bytesRead = sourceStream.Read(buffer, 0, buffer.Length);
while (bytesRead > 0)
{
bytesRead = sourceStream.Read(buffer, 0, buffer.Length);
foreach (byte b in buffer)
{
attachmentBytes.Add(b);
}
}
FileStream outputStream = File.Create(outputPath);
foreach (byte b in attachmentBytes)
{
byte[] barr = new byte[1];
barr[0] = b;
outputStream.Write(barr, 0, 1);
}
outputStream.Close();
sourceStream.Close();
command.Transaction.Commit();
Возможно ли, что повреждение происходит при обработке клиентом ваших вставок? Например. преждевременное усечение, или использовать использование аргумента varchar() vs. nvarchar(), переданного SQL, или char vs. binary? Woudl вы хотите опубликовать код, который вы используете для загрузки контента в потоки и код, используемый для доступа к файловому потоку? –
Спасибо за ответ, я отредактировал мой вопрос с моим кодом. Я не уверен, что вы подразумеваете под неправильным аргументом типа, поле в sql-сервере имеет тип Varbinary (max) FILESTREAM). – Jack