gpt4 book ai didi

c# - 某些文件被 SQL Server FileStream 损坏

转载 作者:太空狗 更新时间:2023-10-30 00:58:16 25 4
gpt4 key购买 nike

我正在使用 FILESTREAM 将文件保存到 SQL Server 2008 (Express) 数据库,我遇到的问题是某些文件似乎在这个过程中被损坏了。

例如,如果我以一种较新的格式(docx 或 xslx)保存一个 word 或 excel 文档,那么当我尝试打开该文件时,我收到一条错误消息,指出数据已损坏,我是否需要 word/excel 尝试恢复它,如果我单击是,office 能够“恢复”数据并以兼容模式打开文件。

但是,如果我先压缩文件,然后在提取内容后,我就可以毫无问题地打开文件。奇怪的是,如果我将一个 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();

最佳答案

您读取的代码不正确:

  while (bytesRead > 0)
{
bytesRead = sourceStream.Read(buffer, 0, buffer.Length);
foreach (byte b in buffer)
{
attachmentBytes.Add(b);
}

}

如果 bytesRead 小于 buffer.Length,您仍将整个缓冲区添加到 attachementBytes。因此,您总是通过在字节读取后的最后一个缓冲区末尾添加任何垃圾来破坏返回的文档。

除此之外,请允许我有一个真正的 WTF 时刻。以 List<byte> 形式读取流??来吧!首先,我不明白为什么您需要先读入中间内存存储的原因。您可以简单地逐个读取缓冲区并将每个缓冲区直接写入 outputStream。其次,如果您必须使用中间内存存储,请使用 MemoryStream , 不是 List<byte> .

关于c# - 某些文件被 SQL Server FileStream 损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3190590/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com