从 MemoryStream 创建的某些文件已损坏
Certain files created from MemoryStream are corrupt
我有代码将包含文件名和二进制数据的对象列表从数据库传递到创建所有文件的循环。我遇到的问题是下面的代码执行并似乎正确地创建了文件(文件名和大小符合预期)但是,大多数文件在打开时都是 "corrupt"。文件类型从图像 (jpg/png) 到 Word 文档、Powerpoint 演示文稿和 PDF 文件不等。奇怪的是 PDF 文件完美运行,其他一切都是 "corrupt"
我的代码如下(attachment
是循环中的对象,路径已经在这个阶段创建)
if(Directory.Exists(attachmentPath))
{
string absolutePath = attachmentPath + "\importfiles\" + parentfolders + "\";
// no need to check if it exists as it will ignore if it does
Directory.CreateDirectory(absolutePath);
absolutePath += filename;
try
{
byte[] byteStream = null;
object objSave = null;
objSave = attachment.Image;
BinaryFormatter tmpBinF = new BinaryFormatter();
MemoryStream tmpMemStrm = new MemoryStream();
tmpBinF.Serialize(tmpMemStrm, objSave);
byteStream = tmpMemStrm.ToArray();
// Delete the file if it exists.
if (File.Exists(absolutePath))
{
File.Delete(absolutePath);
}
// Create the file.
using (FileStream fs = File.Create(absolutePath))
{
fs.Write(byteStream, 0, byteStream.Length);
fs.Dispose();
}
}
catch (Exception ex)
{
Exceptions.Text += ex.ToString();
}
}
我使用了 MSDN and followed this 教程中的提示,但无法弄清楚为什么会这样。
感谢 Amy 指出我的方法存在的问题,如果有人需要,这里是我更新的代码,其中考虑了她的回答。我还扩展了它以在数据库中的 table 上添加一条日志记录以备后用。
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
是字节数组,只需将其写入文件流即可。完全忘记内存流和二进制格式化程序。
Binary Formatter class 用于将 .Net class 序列化为字节数组。但是您已经有了一个字节数组,因此不需要该步骤并且是问题的根源。仅当使用相同的二进制格式化程序在数据库中创建 blob 时,才适合使用二进制格式化程序。但是你存储的是文件,而不是 .Net 对象,所以它在这里没有用。
我不确定为什么 PDF 会加载而其他文件不会加载。您必须使用十六进制编辑器检查文件以查看发生了什么变化。
我有代码将包含文件名和二进制数据的对象列表从数据库传递到创建所有文件的循环。我遇到的问题是下面的代码执行并似乎正确地创建了文件(文件名和大小符合预期)但是,大多数文件在打开时都是 "corrupt"。文件类型从图像 (jpg/png) 到 Word 文档、Powerpoint 演示文稿和 PDF 文件不等。奇怪的是 PDF 文件完美运行,其他一切都是 "corrupt"
我的代码如下(attachment
是循环中的对象,路径已经在这个阶段创建)
if(Directory.Exists(attachmentPath))
{
string absolutePath = attachmentPath + "\importfiles\" + parentfolders + "\";
// no need to check if it exists as it will ignore if it does
Directory.CreateDirectory(absolutePath);
absolutePath += filename;
try
{
byte[] byteStream = null;
object objSave = null;
objSave = attachment.Image;
BinaryFormatter tmpBinF = new BinaryFormatter();
MemoryStream tmpMemStrm = new MemoryStream();
tmpBinF.Serialize(tmpMemStrm, objSave);
byteStream = tmpMemStrm.ToArray();
// Delete the file if it exists.
if (File.Exists(absolutePath))
{
File.Delete(absolutePath);
}
// Create the file.
using (FileStream fs = File.Create(absolutePath))
{
fs.Write(byteStream, 0, byteStream.Length);
fs.Dispose();
}
}
catch (Exception ex)
{
Exceptions.Text += ex.ToString();
}
}
我使用了 MSDN and followed this 教程中的提示,但无法弄清楚为什么会这样。
感谢 Amy 指出我的方法存在的问题,如果有人需要,这里是我更新的代码,其中考虑了她的回答。我还扩展了它以在数据库中的 table 上添加一条日志记录以备后用。
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
是字节数组,只需将其写入文件流即可。完全忘记内存流和二进制格式化程序。
Binary Formatter class 用于将 .Net class 序列化为字节数组。但是您已经有了一个字节数组,因此不需要该步骤并且是问题的根源。仅当使用相同的二进制格式化程序在数据库中创建 blob 时,才适合使用二进制格式化程序。但是你存储的是文件,而不是 .Net 对象,所以它在这里没有用。
我不确定为什么 PDF 会加载而其他文件不会加载。您必须使用十六进制编辑器检查文件以查看发生了什么变化。