【发布时间】:2010-07-06 22:07:45
【问题描述】:
我正在使用 FILESTREAM 将文件保存到 SQL Server 2008 (Express) 数据库,我遇到的问题是某些文件似乎在此过程中损坏了。
例如,如果我以一种较新的格式(docx 或 xslx)保存 word 或 excel 文档,那么当我尝试打开文件时,我会收到一条错误消息,指出数据已损坏,我想要 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();
【问题讨论】:
-
可能是您的客户端处理插入时发生损坏?例如。过早截断,或使用传递给 SQL 的 varchar() 与 nvarchar() 参数类型,或 char 与二进制?您是否愿意发布用于将内容上传到文件流中的代码以及用于访问文件流的代码?
-
感谢您的回复,我用我的代码编辑了我的问题。我不确定您使用错误类型参数是什么意思,sql-server 中的字段类型为 Varbinary(max) FILESTREAM)。
标签: c# sql-server-2008 filestream