C#接收邮件附件

接收邮件类

using System;
using System.Net.Sockets;
using System.Net;
using System.Security.Cryptography;
using System.IO;
using System.Data;

namespace Common
{

    /// <summary> 
    /// 获取邮件的类 
    /// </summary> 
    public class POP3
    {
        private string m_Address = "127.0.0.1";

        private int m_Port = 110;

        public POP3(string p_Address, int p_Port)
        {
            m_Address = p_Address;
            m_Port = p_Port;
        }

        /// <summary> 
        /// 获取Mail列表 
        /// </summary> 
        /// <param name="p_Name">用户名</param> 
        /// <param name="p_PassWord">密码</param> 
        /// <returns>Mail信息</returns> 
        public DataTable GetMailTable(string p_Name, string p_PassWord)
        {
            POP3Client _Client = new POP3Client();
            _Client.UserName = p_Name;
            _Client.PassWord = p_PassWord;
            _Client.Client = new TcpClient();
            _Client.Client.BeginConnect(m_Address, m_Port, new AsyncCallback(OnConnectRequest), _Client);
            while (!_Client.ReturnEnd)
            {
                //System.Windows.Forms.Application.DoEvents();
            }
            if (_Client.Error.Length != 0) throw new Exception("错误信息!" + _Client.Error);
            return _Client.MailTable;
        }


        /// <summary> 
        /// 获取邮件内容 
        /// </summary> 
        /// <param name="p_Name">名称</param> 
        /// <param name="p_PassWord">密码</param> 
        /// <param name="p_MailIndex">邮件编号</param> 
        /// <returns>数据集</returns> 
        public DataTable GetMail(string p_Name, string p_PassWord, int p_MailIndex)
        {
            POP3Client _Client = new POP3Client();
            _Client.UserName = p_Name;
            _Client.PassWord = p_PassWord;
            _Client.Client = new TcpClient();
            _Client.ReadIndex = p_MailIndex;
            _Client.Client.BeginConnect(m_Address, m_Port, new AsyncCallback(OnConnectRequest), _Client);
            while (!_Client.ReturnEnd)
            {
                //System.Windows.Forms.Application.DoEvents();
            }
            if (_Client.Error.Length != 0) throw new Exception("错误信息!" + _Client.Error);
            return _Client.MailTable;
        }

        private class POP3Client
        {
            public TcpClient Client;

            public string UserName = "";

            public string PassWord = "";

            public bool ReturnEnd = false;

            public DataTable MailDataTable = new DataTable();

            public DataTable MailTable = new DataTable();

            public string Error = "";

            public bool ReadEnd = false;

            public int ReadIndex = -1;


            public POP3Client()
            {
                MailDataTable.Columns.Add("NUM");
                MailDataTable.Columns.Add("Size");
                MailDataTable.Columns.Add("Form");
                MailDataTable.Columns.Add("To");
                MailDataTable.Columns.Add("Subject");
                MailDataTable.Columns.Add("Date");

                MailTable.Columns.Add("Type", typeof(string));
                MailTable.Columns.Add("Text", typeof(object));
                MailTable.Columns.Add("Name", typeof(string));
            }

            private int m_SendMessage = 0;
            private int m_TOPIndex = 1;

            /// <summary> 
            /// 获取下一个登陆到获取列表需要的命令 
            /// </summary> 
            /// <param name="p_Value"></param> 
            /// <returns></returns> 
            public byte[] GetSendBytes(byte[] p_Value)
            {
                ReadEnd = false;
                string _Value = System.Text.Encoding.Default.GetString(p_Value).Replace("\0", "");
                if (_Value.IndexOf("+OK") == 0)
                {
                    m_SendMessage++;
                    switch (m_SendMessage)
                    {
                        case 1:
                            return System.Text.Encoding.ASCII.GetBytes("USER " + UserName + "\r\n");
                        case 2:
                            return System.Text.Encoding.ASCII.GetBytes("PASS " + PassWord + "\r\n");
                        case 3:
                            ReadEnd = true;
                            if (ReadIndex != -1)
                            {
                                m_SendMessage = 5;
                                return System.Text.Encoding.ASCII.GetBytes("RETR " + ReadIndex.ToString() + "\r\n");
                            }
                            else
                            {
                                return System.Text.Encoding.ASCII.GetBytes("LIST\r\n");
                            }
                        case 4:
                            string[] _List = _Value.Split(new char[] { '\r', '\n', '.' }, StringSplitOptions.RemoveEmptyEntries);
                            for (int i = 1; i != _List.Length; i++)
                            {
                                string[] _MaliSize = _List[i].Split(' ');
                                MailDataTable.Rows.Add(new object[] { _MaliSize[0], _MaliSize[1] });
                            }
                            if (MailDataTable.Rows.Count == 0)
                            {
                                ReturnEnd = true;
                                return new byte[0];
                            }
                            else
                            {
                                ReadEnd = true;
                                m_TOPIndex = 1;
                                return System.Text.Encoding.ASCII.GetBytes("TOP 1\r\n");
                            }
                        case 5:
                            System.Text.RegularExpressions.Regex _Regex = new System.Text.RegularExpressions.Regex(@"(?<=Date: ).*?(\r\n)+");
                            System.Text.RegularExpressions.MatchCollection _Collection = _Regex.Matches(_Value);
                            if (_Collection.Count != 0) MailDataTable.Rows[m_TOPIndex - 1]["Date"] = GetReadText(_Collection[0].Value);

                            System.Text.RegularExpressions.Regex _RegexFrom = new System.Text.RegularExpressions.Regex(@"(?<=From: ).*?(\r\n)+");
                            System.Text.RegularExpressions.MatchCollection _CollectionForm = _RegexFrom.Matches(_Value);
                            if (_CollectionForm.Count != 0) MailDataTable.Rows[m_TOPIndex - 1]["Form"] = GetReadText(_CollectionForm[0].Value);


                            System.Text.RegularExpressions.Regex _RegexTo = new System.Text.RegularExpressions.Regex(@"(?<=To: ).*?(\r\n)+");
                            System.Text.RegularExpressions.MatchCollection _CollectionTo = _RegexTo.Matches(_Value);
                            if (_CollectionTo.Count != 0) MailDataTable.Rows[m_TOPIndex - 1]["To"] = GetReadText(_CollectionTo[0].Value);

                            System.Text.RegularExpressions.Regex _RegexSubject = new System.Text.RegularExpressions.Regex(@"(?<=Subject: ).*?(\r\n)+");
                            System.Text.RegularExpressions.MatchCollection _CollectionSubject = _RegexSubject.Matches(_Value);
                            if (_CollectionSubject.Count != 0) MailDataTable.Rows[m_TOPIndex - 1]["Subject"] = GetReadText(_CollectionSubject[0].Value);

                            m_TOPIndex++;
                            m_SendMessage--;
                            ReadEnd = true;
                            if (m_TOPIndex > MailDataTable.Rows.Count)
                            {
                                ReturnEnd = true;
                                return System.Text.Encoding.ASCII.GetBytes("QUIT");
                            }
                            else
                            {
                                return System.Text.Encoding.ASCII.GetBytes("TOP " + m_TOPIndex.ToString() + "\r\n");
                            }
                        case 6:
                            GetMailText(_Value);
                            ReturnEnd = true;
                            return System.Text.Encoding.ASCII.GetBytes("QUIT");

                    }
                }
                Error = _Value;
                ReturnEnd = true;
                return new byte[0];
            }

            /// <summary> 
            /// 转换文字里的字符集 
            /// </summary> 
            /// <param name="p_Text"></param> 
            /// <returns></returns> 
            public string GetReadText(string p_Text)
            {
                System.Text.RegularExpressions.Regex _Regex = new System.Text.RegularExpressions.Regex(@"(?<=\=\?).*?(\?\=)+");
                System.Text.RegularExpressions.MatchCollection _Collection = _Regex.Matches(p_Text);
                string _Text = p_Text;
                foreach (System.Text.RegularExpressions.Match _Match in _Collection)
                {
                    string _Value = "=?" + _Match.Value;
                    if (_Value[0] == '=')
                    {
                        string[] _BaseData = _Value.Split('?');
                        if (_BaseData.Length == 5)
                        {
                            System.Text.Encoding _Coding = System.Text.Encoding.GetEncoding(_BaseData[1]);
                            _Text = _Text.Replace(_Value, _Coding.GetString(Convert.FromBase64String(_BaseData[3])));
                        }
                    }
                    else
                    {
                    }
                }
                return _Text;
            }


            #region 获取邮件正文 和 附件
            /// <summary> 
            /// 获取文字主体 
            /// </summary> 
            /// <param name="p_Mail"></param> 
            /// <returns></returns> 
            public void GetMailText(string p_Mail)
            {
                string _ConvertType = GetTextType(p_Mail, "\r\nContent-Type: ", ";");
                if (_ConvertType.Length == 0)
                {
                    _ConvertType = GetTextType(p_Mail, "\r\nContent-Type: ", "\r");
                }
                int _StarIndex = -1;
                int _EndIndex = -1;
                string _ReturnText = "";
                string _Transfer = "";
                string _Boundary = "";
                string _EncodingName = GetTextType(p_Mail, "charset=\"", "\"").Replace("\"", "");
                System.Text.Encoding _Encoding = System.Text.Encoding.Default;
                if (_EncodingName != "") _Encoding = System.Text.Encoding.GetEncoding(_EncodingName);
                switch (_ConvertType)
                {
                    case "text/html;":
                        _Transfer = GetTextType(p_Mail, "\r\nContent-Transfer-Encoding: ", "\r\n").Trim();
                        _StarIndex = p_Mail.IndexOf("\r\n\r\n");
                        if (_StarIndex != -1) _ReturnText = p_Mail.Substring(_StarIndex, p_Mail.Length - _StarIndex);
                        switch (_Transfer)
                        {
                            case "8bit":

                                break;
                            case "quoted-printable":
                                _ReturnText = DecodeQuotedPrintable(_ReturnText, _Encoding);
                                break;
                            case "base64":
                                _ReturnText = DecodeBase64(_ReturnText, _Encoding);
                                break;
                        }
                        MailTable.Rows.Add(new object[] { "text/html", _ReturnText });
                        break;
                    case "text/plain;":
                        _Transfer = GetTextType(p_Mail, "\r\nContent-Transfer-Encoding: ", "\r\n").Trim();
                        _StarIndex = p_Mail.IndexOf("\r\n\r\n");
                        if (_StarIndex != -1) _ReturnText = p_Mail.Substring(_StarIndex, p_Mail.Length - _StarIndex);
                        switch (_Transfer)
                        {
                            case "8bit":

                                break;
                            case "quoted-printable":
                                _ReturnText = DecodeQuotedPrintable(_ReturnText, _Encoding);
                                break;
                            case "base64":
                                _ReturnText = DecodeBase64(_ReturnText, _Encoding);
                                break;
                        }
                        MailTable.Rows.Add(new object[] { "text/plain", _ReturnText });
                        break;
                    case "multipart/alternative;":
                        _Boundary = GetTextType(p_Mail, "boundary=\"", "\"").Replace("\"", "");
                        _StarIndex = p_Mail.IndexOf("--" + _Boundary + "\r\n");
                        if (_StarIndex == -1) return;
                        while (true)
                        {
                            _EndIndex = p_Mail.IndexOf("--" + _Boundary, _StarIndex + _Boundary.Length);
                            if (_EndIndex == -1) break;
                            GetMailText(p_Mail.Substring(_StarIndex, _EndIndex - _StarIndex));
                            _StarIndex = _EndIndex;
                        }
                        break;
                    case "multipart/mixed;":
                        _Boundary = GetTextType(p_Mail, "boundary=\"", "\"").Replace("\"", "");
                        _StarIndex = p_Mail.IndexOf("--" + _Boundary + "\r\n");
                        if (_StarIndex == -1) return;
                        while (true)
                        {
                            _EndIndex = p_Mail.IndexOf("--" + _Boundary, _StarIndex + _Boundary.Length);
                            if (_EndIndex == -1) break;
                            GetMailText(p_Mail.Substring(_StarIndex, _EndIndex - _StarIndex));
                            _StarIndex = _EndIndex;
                        }
                        break;
                    default:
                        if (_ConvertType.IndexOf("application/") == 0)
                        {
                            _StarIndex = p_Mail.IndexOf("\r\n\r\n");
                            if (_StarIndex != -1)
                                _ReturnText = p_Mail.Substring(_StarIndex, p_Mail.Length - _StarIndex);
                            _Transfer = GetTextType(p_Mail, "\r\nContent-Transfer-Encoding: ", "\r\n").Trim();
                            string _Name = GetTextType(p_Mail, "filename=\"", "\"").Replace("\"", "");

                            if (_Name == "")
                            {
                                _Name = GetTextType(p_Mail, "filename=[\\s\\S]*\"", "\"").Replace("\"", "");
                            }

                            _Name = GetReadText(_Name);

                            if (_Name.ToUpper().Contains(".ZIP"))
                            {
                                //_ReturnText = _ReturnText.Trim();
                            }
                            byte[] _FileBytes = new byte[0];
                            switch (_Transfer)
                            {
                                case "base64":
                                    _FileBytes = Convert.FromBase64String(_ReturnText);
                                    break;
                            }
                            MailTable.Rows.Add(new object[] { "application/octet-stream", _FileBytes, _Name });

                        }
                        break;
                }
            }

            /// <summary> 
            /// 获取类型(正则) 
            /// </summary> 
            /// <param name="p_Mail">原始文字</param> 
            /// <param name="p_TypeText">前文字</param> 
            /// <param name="p_End">结束文字</param> 
            /// <returns>符合的记录</returns> 
            public string GetTextType(string p_Mail, string p_TypeText, string p_End)
            {
                System.Text.RegularExpressions.Regex _Regex = new System.Text.RegularExpressions.Regex(@"(?<=" + p_TypeText + ").*?(" + p_End + ")+");
                System.Text.RegularExpressions.MatchCollection _Collection = _Regex.Matches(p_Mail);
                if (_Collection.Count == 0) return "";
                return _Collection[0].Value;
            }

            /// <summary> 
            /// QuotedPrintable编码接码 
            /// </summary> 
            /// <param name="p_Text">原始文字</param> 
            /// <param name="p_Encoding">编码方式</param> 
            /// <returns>接码后信息</returns> 
            public string DecodeQuotedPrintable(string p_Text, System.Text.Encoding p_Encoding)
            {
                System.IO.MemoryStream _Stream = new System.IO.MemoryStream();
                char[] _CharValue = p_Text.ToCharArray();
                for (int i = 0; i != _CharValue.Length; i++)
                {
                    switch (_CharValue[i])
                    {
                        case '=':
                            if (_CharValue[i + 1] == '\r' || _CharValue[i + 1] == '\n')
                            {
                                i += 2;
                            }
                            else
                            {
                                try
                                {
                                    _Stream.WriteByte(Convert.ToByte(_CharValue[i + 1].ToString() + _CharValue[i + 2].ToString(), 16));
                                    i += 2;
                                }
                                catch
                                {
                                    _Stream.WriteByte(Convert.ToByte(_CharValue[i]));
                                }
                            }
                            break;
                        default:
                            _Stream.WriteByte(Convert.ToByte(_CharValue[i]));
                            break;
                    }
                }
                return p_Encoding.GetString(_Stream.ToArray());
            }

            /// <summary> 
            /// 解码BASE64 
            /// </summary> 
            /// <param name="p_Text"></param> 
            /// <param name="p_Encoding"></param> 
            /// <returns></returns> 
            public string DecodeBase64(string p_Text, System.Text.Encoding p_Encoding)
            {
                if (p_Text.Trim().Length == 0) return "";
                byte[] _ValueBytes = Convert.FromBase64String(p_Text);
                return p_Encoding.GetString(_ValueBytes);
            }
            #endregion


        }

        /// <summary> 
        /// 连接事件 
        /// </summary> 
        /// <param name="ar"></param> 
        private void OnConnectRequest(IAsyncResult ar)
        {
            POP3Client _Client = (POP3Client)ar.AsyncState;
            byte[] _ReadBytes = new byte[0];
            _Client.Client.Client.BeginReceive(_ReadBytes, 0, 0, SocketFlags.None, new AsyncCallback(OnWrite), _Client);
        }

        /// <summary> 
        /// 连接事件 
        /// </summary> 
        /// <param name="ar"></param> 
        private void OnSend(IAsyncResult ar)
        {
            POP3Client _Client = (POP3Client)ar.AsyncState;
            byte[] _ReadBytes = new byte[0];
            _Client.Client.Client.BeginReceive(_ReadBytes, 0, 0, SocketFlags.None, new AsyncCallback(OnWrite), _Client);
        }

        /// <summary> 
        /// 连接事件 
        /// </summary> 
        /// <param name="ar"></param> 
        private void OnWrite(IAsyncResult ar)
        {
            POP3Client _Client = (POP3Client)ar.AsyncState;
            byte[] _WriteBytes = new byte[_Client.Client.Client.ReceiveBufferSize];
            _Client.Client.Client.Receive(_WriteBytes);
            if (_Client.ReadEnd) 
                _WriteBytes = ReadEnd(_WriteBytes, _Client);
            byte[] _SendBytes = _Client.GetSendBytes(_WriteBytes);
            if (_SendBytes.Length == 0) return;
            _Client.Client.Client.BeginSend(_SendBytes, 0, _SendBytes.Length, SocketFlags.None, new AsyncCallback(OnSend), _Client);
        }

        /// <summary> 
        /// 获取知道获取到. 否则一直获取数据 
        /// </summary> 
        /// <param name="p_Value"></param> 
        /// <returns></returns> 
        private byte[] ReadEnd(byte[] p_Value, POP3Client p_Client)
        {
            if (System.Text.Encoding.ASCII.GetString(p_Value).IndexOf("\r\n.\r\n") != -1) return p_Value;
            MemoryStream _Stream = new MemoryStream();
            _Stream.Write(p_Value, 0, p_Value.Length);
            while (true)
            {
                byte[] _WriteBytes = new byte[p_Client.Client.ReceiveBufferSize];
                p_Client.Client.Client.Receive(_WriteBytes);
                _Stream.Write(_WriteBytes, 0, _WriteBytes.Length);
                System.Threading.Thread.Sleep(100);
                if (System.Text.Encoding.ASCII.GetString(_WriteBytes).IndexOf("\r\n.\r\n") != -1)
                    return _Stream.ToArray();
            }
        }

    }
}
View Code


解压缩方法(分ZIP和RAR2种)

        /// <summary>
        /// 解压功能(解压压缩文件到指定目录)
        /// </summary>
        /// <param name="FileToUpZip">待解压的文件</param>
        /// <param name="ZipedFolder">指定解压目标目录</param>
        public static void UnZip(string FileToUpZip, string ZipedFolder, string Password)
        {
            if (!File.Exists(FileToUpZip))
            {
                return;
            }

            if (!Directory.Exists(ZipedFolder))
            {
                Directory.CreateDirectory(ZipedFolder);
            }

            ZipInputStream s = null;
            ZipEntry theEntry = null;

            string fileName;
            FileStream streamWriter = null;
            try
            {
                s = new ZipInputStream(File.OpenRead(FileToUpZip));
                s.Password = Password;
                while ((theEntry = s.GetNextEntry()) != null)
                {
                    if (theEntry.Name != String.Empty)
                    {
                        fileName = Path.Combine(ZipedFolder, theEntry.Name);
                        ///判断文件路径是否是文件夹
                        if (fileName.EndsWith("/") || fileName.EndsWith("\\"))
                        {
                            Directory.CreateDirectory(fileName);
                            continue;
                        }

                        streamWriter = File.Create(fileName);
                        int size = 2048;
                        byte[] data = new byte[2048];
                        while (true)
                        {
                            size = s.Read(data, 0, data.Length);
                            if (size > 0)
                            {
                                streamWriter.Write(data, 0, size);
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }
            }
            finally
            {
                if (streamWriter != null)
                {
                    streamWriter.Close();
                    streamWriter = null;
                }
                if (theEntry != null)
                {
                    theEntry = null;
                }
                if (s != null)
                {
                    s.Close();
                    s = null;
                }
                GC.Collect();
                GC.Collect(1);
            }
        }

        /// <summary>
        /// 利用 WinRAR 进行解压缩
        /// </summary>
        /// <param name="path">文件解压路径(绝对)</param>
        /// <param name="rarPath">将要解压缩的 .rar 文件的存放目录(绝对路径)</param>
        /// <param name="rarName">将要解压缩的 .rar 文件名(包括后缀)</param>
        /// <returns>true 或 false。解压缩成功返回 true,反之,false。</returns>
        public static bool UnRAR(string path, string rarPath, string rarName)
        {
            bool flag = false;
            string rarexe;
            RegistryKey regkey;
            Object regvalue;
            string cmd;
            ProcessStartInfo startinfo;
            Process process;
            try
            {
                regkey = Registry.ClassesRoot.OpenSubKey(@"WinRAR\shell\open\command");
                regvalue = regkey.GetValue("");
                rarexe = regvalue.ToString();
                regkey.Close();
                rarexe = rarexe.Substring(1, rarexe.Length - 7);

                Directory.CreateDirectory(path);
                //解压缩命令,相当于在要压缩文件(rarName)上点右键->WinRAR->解压到当前文件夹
                cmd = string.Format("x {0} {1} -y",
                                    rarName,
                                    path);
                startinfo = new ProcessStartInfo();
                startinfo.FileName = rarexe;
                startinfo.Arguments = cmd;
                startinfo.WindowStyle = ProcessWindowStyle.Hidden;

                startinfo.WorkingDirectory = rarPath;
                process = new Process();
                process.StartInfo = startinfo;
                process.Start();
                process.WaitForExit();
                if (process.HasExited)
                {
                    flag = true;
                }
                process.Close();
            }
            catch (Exception e)
            {
                throw e;
            }
            return flag;
        }
View Code

 

调用方法

        public void GetMailFile()
        {

            POP3 pop = new POP3("pop.XXXX.com", 110);
            DataTable dt = pop.GetMailTable("XXXXXX.com", "*************");

            foreach(DataRow dr in dt.Rows)
            {
                if ("application/octet-stream".Equals(dr[0]))
                {
                    byte[] context = dr[1] as byte[];
                    if (dr[2] == null && dr[2].ToString().Length < 4)
                    {
                        continue;
                    }
                    //XXXX.csv.zip
                    string fileName = dr[2].ToString();
                    fileName = Server.MapPath(@"~\TemplateFile\" + fileName);
                    using (FileStream fileStream = System.IO.File.Create(fileName))
                    {
                        fileStream.Write(context, 0, context.Length);
                    }

                    FileZipOperatorUtil.UnRAR(Server.MapPath(@"~\TemplateFile\"), Server.MapPath(@"~\TemplateFile\"), dr[2].ToString());
                }
            }
        }
View Code

 

posted @ 2015-05-22 17:22  终极程序猿  阅读(1957)  评论(0编辑  收藏  举报