Я сохраняю файлы в базе данных SQL Server 2008 (Express) с помощью FILESTREAM, проблема в том, что некоторые файлы, похоже, повреждаются в процессе.
Например, если я сохраняюДокумент Word или Excel в одном из более новых форматов (docx или xslx), а затем при попытке открыть файл выдает сообщение об ошибке, в котором говорится, что данные повреждены, и я хотел бы, чтобы word / excel попытался их восстановить, если янажмите «Да», офис сможет «восстановить» данные и откроет файл в режиме совместимости.
Однако, если я сначала заархивирую файл, то после извлечения содержимого смогу открыть файл без проблем.Как ни странно, если я сохраняю mp3-файл в базе данных, у меня возникает обратная проблема, я могу открыть файл без проблем, но если я сохранил заархивированную версию mp3, я даже не могу извлечь содержимое этого zip-файла.Когда я попытался сохранить файл в формате 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();