C# 从MemoryStream创建的某些文件已损坏
我的代码将包含文件名和二进制数据的对象列表从数据库传递到创建所有文件的循环。我遇到的问题是,下面的代码执行并似乎正确创建了文件(文件名和大小与预期一致),但是,大多数文件在打开时都“损坏”。文件类型从图像(jpg/png)到Word文档、Powerpoint演示文稿和PDF文件不等。奇怪的是,PDF文件工作得很好,其他一切都“损坏” 下面是我的代码(C# 从MemoryStream创建的某些文件已损坏,c#,filestream,memorystream,C#,Filestream,Memorystream,我的代码将包含文件名和二进制数据的对象列表从数据库传递到创建所有文件的循环。我遇到的问题是,下面的代码执行并似乎正确创建了文件(文件名和大小与预期一致),但是,大多数文件在打开时都“损坏”。文件类型从图像(jpg/png)到Word文档、Powerpoint演示文稿和PDF文件不等。奇怪的是,PDF文件工作得很好,其他一切都“损坏” 下面是我的代码(附件是循环中的对象,此阶段已创建路径) 我使用了本教程中的提示并遵循了本教程的内容,但我不明白为什么会发生这种情况 感谢Amy指出我的方法存在的问题
附件
是循环中的对象,此阶段已创建路径)
我使用了本教程中的提示并遵循了本教程的内容,但我不明白为什么会发生这种情况
感谢Amy指出我的方法存在的问题,如果有人需要,这里是考虑到她的答案的我的更新代码。我还对其进行了扩展,在DB中的表上添加了日志记录,以供以后使用
if (Directory.Exists(attachmentPath))
{
// build path from the parts
string absolutePath = attachmentPath + "\\importfiles\\" + parentfolders + "\\";
// no need to check if it exists as it will ignore if it does
Directory.CreateDirectory(absolutePath);
absolutePath += filename;
byte[] file = attachment.Image;
try
{
// Delete the file if it exists.
if (File.Exists(absolutePath))
{
File.Delete(absolutePath);
}
// Create the file.
using (FileStream fs = File.Create(absolutePath))
{
fs.Write(file, 0, file.Length);
}
// start logging to the database
// add the Stored procedure
string SP = "sp_add_attachment";
// create the connection & command objects
MySqlConnection myConnection1 = new MySqlConnection(WPConnectionString);
MySqlCommand cmd1;
try
{
// open the connection
myConnection1.Open();
cmd1 = myConnection1.CreateCommand();
// assign the stored procedure string to the command
cmd1.CommandText = SP;
// define the command type
cmd1.CommandType = CommandType.StoredProcedure;
// pass the parameters to the Store Procedure
cmd1.Parameters.AddWithValue("@AttachmentID", attachment.ID);
cmd1.Parameters["@AttachmentID"].Direction = ParameterDirection.Input;
cmd1.Parameters.AddWithValue("@subpath", parentfolders);
cmd1.Parameters["@subpath"].Direction = ParameterDirection.Input;
cmd1.Parameters.AddWithValue("@filename", filename);
cmd1.Parameters["@filename"].Direction = ParameterDirection.Input;
// execute the command
int output = cmd1.ExecuteNonQuery();
// close the connection
myConnection1.Close();
}
catch (Exception ex)
{
Exceptions.Text += "MySQL Exception when logging:" + ex.ToString();
}
}
catch (Exception ex)
{
Exceptions.Text += ex.ToString();
}
}
我认为使用BinaryFormatter不合适。如果
attachment.Image
是字节数组,只需将其写入文件流即可。完全忘记内存流和二进制格式化程序
二进制格式化程序类用于将.Net类序列化为字节数组。不过,您已经有了一个字节数组,因此不需要执行该步骤,这是问题的根源。只有在使用相同的二进制格式化程序在数据库中创建blob时,使用二进制格式化程序才合适。但是您存储的是文件,而不是.Net对象,因此它在这里没有用处
我不知道为什么PDF会加载而其他文件不会加载。您必须使用十六进制编辑器检查文件以查看更改的内容 我认为使用BinaryFormatter不合适。如果
attachment.Image
是字节数组,只需将其写入文件流即可。完全忘记内存流和二进制格式化程序
二进制格式化程序类用于将.Net类序列化为字节数组。不过,您已经有了一个字节数组,因此不需要执行该步骤,这是问题的根源。只有在使用相同的二进制格式化程序在数据库中创建blob时,使用二进制格式化程序才合适。但是您存储的是文件,而不是.Net对象,因此它在这里没有用处
我不知道为什么PDF会加载而其他文件不会加载。您必须使用十六进制编辑器检查文件以查看更改的内容 您可能不需要最后一个
fs.Dispose()
,因为using
的用法暗示了这一点。不过,我怀疑这是问题的原因。谢谢@HoriaComan-我将删除它,因为它不是必需的,当你指出它时,这是非常明显的!)您试图写入的对象是附件。Image
否?它的格式是什么?您如何确定它是一个合适的jpg/png开始,而不仅仅是一个像素矩阵,例如?该对象是一个来自CMS数据库的BLOB。这是“正确的”,因为当我浏览站点(使用相同的数据库)时可以看到输出。我不明白的是,为什么PDF文件可以工作,但其他一切似乎都损坏了。创建PDF文件与创建Word文档有什么不同?我认为使用BinaryFormatter不合适。如果attachment.Image
是字节数组,只需将其写入文件流即可。完全忘记内存流和二进制格式化程序。您可能不需要最后一个fs.Dispose()
,因为使用会暗示这一点。不过,我怀疑这是问题的原因。谢谢@HoriaComan-我将删除它,因为它不是必需的,当你指出它时,这是非常明显的!)您试图写入的对象是附件。Image
否?它的格式是什么?您如何确定它是一个合适的jpg/png开始,而不仅仅是一个像素矩阵,例如?该对象是一个来自CMS数据库的BLOB。这是“正确的”,因为当我浏览站点(使用相同的数据库)时可以看到输出。我不明白的是,为什么PDF文件可以工作,但其他一切似乎都损坏了。创建PDF文件与创建Word文档有什么不同?我认为使用BinaryFormatter不合适。如果attachment.Image
是字节数组,只需将其写入文件流即可。完全忘记内存流和二进制格式化程序。是的,PDF文件工作是这个问题最奇怪的方面,但你的答案是完美的。谢谢,可能是生成的字节流只有四个字节的长度,然后是数组的内容,这是一个序列化的PDF文档。可能是PDF阅读器在输入处理方面非常松懈,他们知道在找到合适的PDF文档之前跳过一些“是”。是的,PDF文件工作是这个问题最奇怪的方面,但你的答案是完美的。谢谢,可能是生成的字节流只有四个字节的长度,然后是数组的内容,这是一个序列化的PDF文档。可能是PDF阅读器在输入处理方面非常松懈,他们知道在找到一个合适的PDF文档之前跳过一些“是”。
if (Directory.Exists(attachmentPath))
{
// build path from the parts
string absolutePath = attachmentPath + "\\importfiles\\" + parentfolders + "\\";
// no need to check if it exists as it will ignore if it does
Directory.CreateDirectory(absolutePath);
absolutePath += filename;
byte[] file = attachment.Image;
try
{
// Delete the file if it exists.
if (File.Exists(absolutePath))
{
File.Delete(absolutePath);
}
// Create the file.
using (FileStream fs = File.Create(absolutePath))
{
fs.Write(file, 0, file.Length);
}
// start logging to the database
// add the Stored procedure
string SP = "sp_add_attachment";
// create the connection & command objects
MySqlConnection myConnection1 = new MySqlConnection(WPConnectionString);
MySqlCommand cmd1;
try
{
// open the connection
myConnection1.Open();
cmd1 = myConnection1.CreateCommand();
// assign the stored procedure string to the command
cmd1.CommandText = SP;
// define the command type
cmd1.CommandType = CommandType.StoredProcedure;
// pass the parameters to the Store Procedure
cmd1.Parameters.AddWithValue("@AttachmentID", attachment.ID);
cmd1.Parameters["@AttachmentID"].Direction = ParameterDirection.Input;
cmd1.Parameters.AddWithValue("@subpath", parentfolders);
cmd1.Parameters["@subpath"].Direction = ParameterDirection.Input;
cmd1.Parameters.AddWithValue("@filename", filename);
cmd1.Parameters["@filename"].Direction = ParameterDirection.Input;
// execute the command
int output = cmd1.ExecuteNonQuery();
// close the connection
myConnection1.Close();
}
catch (Exception ex)
{
Exceptions.Text += "MySQL Exception when logging:" + ex.ToString();
}
}
catch (Exception ex)
{
Exceptions.Text += ex.ToString();
}
}