从sql数据库中选择所有照片

时间:2019-09-24 11:54:20

标签: c# sql

我想将数据库中的所有照片导出到数据表中。然后,我将遍历表并将每个图像保存到磁盘。大约有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;
    }

2 个答案:

答案 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());
        }
    }
相关问题