Как загружать и извлекать большие файлы из электронной почты с помощью оконного сервиса - PullRequest
0 голосов
/ 05 августа 2020

Я использую следующий код в оконном сервисе для загрузки zip-файла определенного формата из вложений электронной почты:

Метод получения электронных писем:

 public void GetdownloadfromGmail()
    {
        try
        {
            ConfigDetails ConfigDetails = new ConfigDetails();
            DataTable SecTable = ConfigDetails.GetConfigTableCol(Constant.Seccurity);
            using (IDbConnection con = Connections.Getsynchconnection())
            {  
                try
                {
                    con.Open();
                    ConnectionState state = con.State;
                    con.Close();
                    if (state == ConnectionState.Open)
                    {
                        SentmailCount = 0;
                    }
                }
                catch (Exception ex)
                {
                    Common.Synch.Factory.LogHelpFactory.log.Error(ex.Message.ToString());
                    if (SentmailCount == 0)
                    {
                        string ContentMessage = "SqlConnection is Not Open :" + ex.Message.ToString();
                        Process SharedProc = new Process();
                        string EmailID = SharedProc.GetReceipientmailid(new Context(new MailContext()), "", 3);
                        string[] Receipients = EmailID.Split(',');
                        
                        //time being profile,pwd is hard coded
                       

                        GmailClient.GmailClient gc = new GmailClient.GmailClient();
                        /*Sending attachment(s) with the mail*/
                        gc.SMTPHost = SecTable.Rows[0]["SmtpHost"].ToString();
                        gc.SMTPPortNumber = Convert.ToInt32(SecTable.Rows[0]["SmtpPort"].ToString());


                        bool IsEnableSsl = Convert.ToBoolean(SecTable.Rows[0]["IsEnableSsl"].ToString());
                        System.Net.NetworkCredential credentials = new System.Net.NetworkCredential(SecTable.Rows[0]["Username"].ToString(), SecTable.Rows[0]["Password"].ToString());
                        System.Net.Mail.MailAddress address = new System.Net.Mail.MailAddress(SecTable.Rows[0]["Username"].ToString(), SecTable.Rows[0]["DisplayName"].ToString());
                        gc.sendMail("Connection", Receipients, ContentMessage, null, "", credentials, address, true, IsEnableSsl);
                        SentmailCount = 1;
                    }
                    return;
                }
            }
            Common.Synch.Factory.LogHelpFactory.log.Info("Start Download Mails From Mailbox");
            //ConfigDetails ConfigDetails = new ConfigDetails();
            //time being profile,pwd is hard coded
           // DataTable SecTable = ConfigDetails.GetConfigTableCol(Constant.Seccurity);
            if (SecTable.Columns["UserName"] == null && SecTable.Columns["Password"] == null)
            {
                throw (new Exception("Invalid Profile settings"));
            }
            using (GmailClient.GmailClient gc = new GmailClient.GmailClient())
            {

                gc.UseSSL = true;
                /*Part to fetch mails from gmail; List<MailMessage> will have all the mails fetched which can be used later to send mails. 
                The attachments get downloaded as the mails are read. 
                The MailMessage only includes the basic header information along with the number of attachments processed. 
                Once all emails are fetched, the client disconnects automatically*/

                //Following property will not delete the email from gmail server if set to False, but deletes if it set to True
                gc.SMTPHost = SecTable.Rows[0]["IncomingEmailHost"].ToString();
                gc.SMTPPortNumber = Convert.ToInt32(SecTable.Rows[0]["IncomingEmailPort"].ToString());
                gc.DeleteProcessedMails = Convert.ToBoolean(SecTable.Rows[0]["DeleteEmail"].ToString());

                ConfigDetails = new ConfigDetails();
                TempPath = ConfigDetails.GetPath(Constant.TempFolder);

                //Default AttachmentPath is the path of dll directory. Howeve it can be set exclusilvely as below.
                gc.AttachmentPath = TempPath + "\\";

                string strUname = SecTable.Rows[0]["Username"].ToString();
                string strPwd = SecTable.Rows[0]["Password"].ToString();
                gc.Connect(strUname, strPwd);
                gc.CopyProcessedMails = Convert.ToBoolean(SecTable.Rows[0]["CopyProcessedEmail"].ToString()); ;
                gc.CopyMailTargetFolder = Convert.ToString(SecTable.Rows[0]["CopyMailTargetFolder"].ToString()); ;
                Common.Synch.Factory.LogHelpFactory.log.Info("Test ");
                if (gc.IsConnected)
                {
                    Common.Synch.Factory.LogHelpFactory.log.Info("Connected");
                    List<MailMessage> mails = gc.GetMailList();
                    Common.Synch.Factory.LogHelpFactory.log.Info("Unread Mail Count:" + mails.Count.ToString()); try
                    {
                        foreach (MailMessage Mail in mails)
                        {
                            try
                            {
                                isDeleted = false;
                                if (null != Mail.Subject)
                                    Common.Synch.Factory.LogHelpFactory.log.Info(Mail.Subject.ToString());
                                else
                                    Common.Synch.Factory.LogHelpFactory.log.Info(Mail.FromEmail + " (no subject)");
                                GetMaiilboxtotable(Mail);
                                //if (isDeleted)
                                //{
                                //Mail.UnRead = false;
                                //Mail.Delete();

                                //}
                            }
                            catch (Exception Ex)
                            {
                                //if (Ex.Message == "Could not save attachment to a file")
                                //{
                                Common.Synch.Factory.LogHelpFactory.log.Info("Error while processing email:" + Ex.Message.ToString());
                                Common.Synch.Factory.LogHelpFactory.log.Info("Subject:" + Mail.Subject + ", From:" + Mail.FromName);
                                //Mail.UnRead = false;
                                //Mail.Delete();
                                //}
                            }
                        }
                    }

                    //if (ListofMails.Count > 0)
                    //{
                    //OutlookClient.MovFolderselection();
                    //}
                    catch (Exception Ex)
                    {
                        //if (ListofMails != null)
                        //{
                        //    Marshal.ReleaseComObject(ListofMails);
                        //}
                        //ListofMails = null;
                        ////OutlookClient.Dispose();
                        mails = null;
                        gc.Dispose();
                        Common.Synch.Factory.LogHelpFactory.log.Error("SearchMails(GetMailFromGmail) failed : ", Ex);
                    }
                    finally
                    {
                        if (m_MailTable.Rows.Count > 0)
                        {
                            SaveEmail();
                            Common.Synch.Factory.LogHelpFactory.log.Info("Save Email Complete");
                        }
                        int Sleeptime = Convert.ToInt32(ConfigDetails.GetResourceSleeptime(Constant.InboundProcess));
                        if (Sleeptime == 0)
                        {
                            Sleeptime = 10000;
                        }
                        ConfigDetails = null;
                        try
                        {
                            Thread.Sleep(Sleeptime);
                        }
                        catch (ThreadAbortException ex)
                        {
                            Common.Synch.Factory.LogHelpFactory.log.Info("Error on thread.Sleep:" + ex.Message.ToString());
                        }

                        try
                        {
                            this.DownLoadCompleteEventArgs(this, new DownLoadCompleteEventArgs("DownLoad Complete"));
                        }
                        catch (Exception ex)
                        {
                            Common.Synch.Factory.LogHelpFactory.log.Info("Error while invoking the thread:" + ex.Message.ToString());
                        }

                        Common.Synch.Factory.LogHelpFactory.log.Info("End Download Mails From Inbox");
                    }
                }
                // Log
            }
        }
        catch (Exception ex)
        {
            Common.Synch.Factory.LogHelpFactory.log.Error(ex.Message.ToString());
        }
    }

Способ сохранения извлеченных файлов в базе данных:

 public void GetMaiilboxtotable(MailMessage Message)
    {
        Common.Synch.Common.DeleteFile(TempPath);
        try
        {
            if (Initalize())
            {
                if (Message.Attachments != null && Message.AttachmentsCount > 0)
                {
                    for (int Count = 0; Count <= Message.AttachmentsCount - 1; Count++)
                    {
                        //if (Message.Attachments[Count].AttachmentAttachmentFileName.Substring(Message.Attachments[Count].AttachmentAttachmentFileName.Length - 3, 3).ToUpper() == "MSG")
                        //{
                        //    Message.Attachments[Count].SaveAsFile(TempPath + "Temp.msg");
                        //    outlookApp = new OutLook.ApplicationClass();

                        //    MsgMail = (OutLook.MailItem)outlookApp.CreateItemFromTemplate(TempPath + "Temp.msg", Type.Missing);

                        //    GetMaiilboxtotable(MsgMail);
                        //    outlookApp = null;
                        //    MsgMail = null;

                        //}
                        if (Message.Attachments[Count].AttachmentFileName.Substring(Message.Attachments[Count].AttachmentFileName.Length - 3, 3).ToUpper() == "ZIP" ||
                            Message.Attachments[Count].AttachmentFileName.Substring(Message.Attachments[Count].AttachmentFileName.Length - 3, 3).ToUpper() == "XML" ||
                            Message.Attachments[Count].AttachmentFileName.Substring(Message.Attachments[Count].AttachmentFileName.Length - 3, 3).ToUpper() == "XLS" ||
                            (Message.Attachments[Count].AttachmentFileName.Substring(Message.Attachments[Count].AttachmentFileName.Length - 3, 3).ToUpper() == "DAT"
                            && Message.Attachments[Count].AttachmentFileName.Substring(0, 2).ToUpper() == "HJ") ||
                            Message.Attachments[Count].AttachmentFileName.Substring(Message.Attachments[Count].AttachmentFileName.Length - 3, 3).ToUpper() == "BIN")
                        {
                            if (m_MailTable.Columns.Count <= 0)
                            {
                                CreateMailTable();
                            }
                            isDeleted = true;
                            DataRow MailRows = m_MailTable.NewRow();
                            MailRows["MailID"] = Message.FromEmail;
                            MailRows["MsgDate"] = Message.ReceivedDate;
                            MailRows["MsgSubject"] = (null == Message.Subject ? string.Empty : Message.Subject);
                            MailRows["CreateDateTime"] = DateTime.Now;
                            //string GwAttachmentName = Message.Attachments[Count].AttachmentFileName;
                            Message.Attachments[Count].DownloadAttachment();// SaveAsFile(TempPath + Message.Attachments[Count].AttachmentFileName);

                            MailRows["AttachmentName"] = Message.Attachments[Count].AttachmentFileName;
                            ConvertBinary ConvertBinary = new ConvertBinary();
                            MailRows["AttachmentFile"] = ConvertBinary.ConverTOBinaryFile(TempPath + "\\" + Message.Attachments[Count].AttachmentFileName);
                            ConvertBinary.Dispose();
                            ConvertBinary = null;
                            //Marshal.ReleaseComObject(synchGwAttachment);
                            m_MailTable.Rows.Add(MailRows);
                            //Log
                            Common.Synch.Factory.LogHelpFactory.log.Info("Add Mail to MailBox Temp Table -" + Message.Attachments[Count].AttachmentFileName);
                        }
                    }
                }

            }
        }
        catch (Exception ex)
        {
            Message = null;
            Common.Synch.Factory.LogHelpFactory.log.Info(Message.Subject + ":" + ex.ToString());
        }

    }

Структура вложения:

введите описание изображения здесь

Во вложении мы отправляем bin-файлы объектов, и эти объекты извлекаются и сохраняются в базе данных.

Проблема: Иногда мы получаем большие файлы, поэтому при извлечении службы зависают и останавливают обработку между ними. Не могли бы вы дать мне несколько советов и идей по решению этой проблемы.

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация, я постараюсь ее предоставить. Заранее спасибо.

1 Ответ

0 голосов
/ 05 августа 2020

Вы используете DataTables. DataTable - это копия реляционных данных в памяти. Таким образом, все данные, которые вы собираетесь сохранить, должны уместиться в памяти. Если у вас много записей, большие записи или и то, и другое, это не годится.

Я предлагаю:

  • распаковать файл во временную папку в локальной файловой системе
  • вставлять в базу данных по одному файлу за раз с помощью SqlCommand

Использовать параметры в вашей команде INSERT (ie вставлять в значения mytable (col1, col2) (@ col1, @ col2) )

...