我想将数据库中的所有照片导出到数据表中。然后,我将遍历表并将每个图像保存到磁盘。大约有7000张照片。
当我开始该过程时,我可以获取大约4000张照片,然后再开始收到错误消息,例如引发了'System.OutOfMemoryException'类型的异常。
如果我更改SQL查询以检索一半的照片(例如3500),则该过程成功完成。 现在,我每次运行代码都可以通过修改SQL来实现我想要的功能,但是我想对代码进行改进,以便返回所有7000张照片。有人可以建议一个更好的过程。
这是我的方法
public static DataTable GetAllPhotos()
{
DataTable dt = new DataTable();
dt.Columns.Add("personId", typeof(string));
dt.Columns.Add("Photo", typeof(Bitmap));
string SQL = "";
byte[] getImg = new byte[0];
byte[] BitmapImg = new byte[0];
string personId = "";
SqlConnection conn = new SqlConnection();
conn.ConnectionString = _connString;
SQL = @"select per.person_id,pho.photo
from person as per
left join photo as pho on per.photo_id = pho.photo_id
where photo is not null";
conn.Open();
SqlDataReader dr = null;
SqlCommand cmd = new SqlCommand(SQL, conn);
dr = cmd.ExecuteReader();
while (dr.Read())
{
try
{
getImg = (byte[])dr["Photo"];
personId = Convert.ToString(dr["person_id"]);
MemoryStream str = new MemoryStream(getImg);
Bitmap bitmap = new Bitmap(Image.FromStream(str));
BitmapImg = ImageToByte(bitmap);
dt.Rows.Add(personId, bitmap);
}
catch (Exception ex)
{
LogWriter.WriteLine(personId + ex.Message.ToString());
}
}
conn.Close();
return dt;
}
答案 0 :(得分:2)
如果您打算将图像保存到磁盘,那么为什么要将它们放入中间数据表中?如果您在读取磁盘时直接将其写出到磁盘会更好吗?如果是这样,假设这些文件是.bmp文件:
public static void DumpAllPhotos()
{
string sql = @"select per.person_id,pho.photo
from person as per
inner join photo as pho on per.photo_id = pho.photo_id";
string folder = @"c:\MyFolder"; // output folder
using (SqlConnection con = new SqlConnection(_connString))
using (SqlCommand cmd = new SqlCommand(sql,con))
{
con.Open();
var rdr = cmd.ExecuteReader();
while (rdr.Read())
{
var bytes = (byte[])rdr["photo"];
var path = Path.Combine(folder, $"{rdr["person_id"].ToString()}.bmp");
File.WriteAllBytes(path, bytes);
}
con.Close();
}
}
答案 1 :(得分:-1)
必须丢弃位图,您使用了太多的句柄。 因此,您的while循环应如下所示:
Exchange
甚至更好:
while (dr.Read())
{
try
{
getImg = (byte[])dr["Photograph"];
personId = Convert.ToString(dr["person_id"]);
MemoryStream str = new MemoryStream(getImg);
Bitmap bitmap = new Bitmap(Image.FromStream(str));
BitmapImg = ImageToByte(bitmap);
dt.Rows.Add(personId, bitmap);
bitmap.Dipose(); // <--- DISPOSE!!
}
catch (Exception ex)
{
LogWriter.WriteLine(personId + ex.Message.ToString());
}
}