苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper爬虫框架(V2.7-含.netcore) HttpHelper官方出品,爬虫框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 开源的爬虫类,支持多种模式和属性 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 11886|回复: 0
打印 上一主题 下一主题

[Mime] MimeReader--读取Mime的帮助类

[复制链接]
跳转到指定楼层
楼主
发表于 2012-12-13 13:25:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
                  MimeReader--读取Mime的帮助类
导读部分
-------------------------------------------------------------------------------------------------------------
C#基类库苏飞版--系列教程导航 http://www.sufeinet.com/thread-655-1-1.html

下载之前你首先要注册成为会员哦,注册之后就可以直接下载啦
更新时间:2012-12-09
最新的MimeReader类下载:
MimeReader.rar (3.05 KB, 下载次数: 80)
这个类是关于MimeReader的帮助类
看下面代码吧
[C#] 纯文本查看 复制代码
/// <summary>
/// 类说明:Assistant
/// 编 码 人:苏飞
/// 联系方式:361983679  
/// 更新网站:[url=http://www.sufeinet.com/thread-655-1-1.html]http://www.sufeinet.com/thread-655-1-1.html[/url]
/// </summary>
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Mime;

namespace DotNet.Utilities
{
    /// <summary>
    /// This class is responsible for parsing a string array of lines
    /// containing a MIME message.
    /// </summary>
    public class MimeReader
    {
        private static readonly char[] HeaderWhitespaceChars = new char[] { ' ', '\t' };

        private Queue<string> _lines;
        /// <summary>
        /// Gets the lines.
        /// </summary>
        /// <value>The lines.</value>
        public Queue<string> Lines
        {
            get
            {
                return _lines;
            }
        }

        private MimeEntity _entity;

        /// <summary>
        /// Initializes a new instance of the <see cref="MimeReader"/> class.
        /// </summary>
        private MimeReader()
        {
            _entity = new MimeEntity();
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="MimeReader"/> class.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <param name="lines">The lines.</param>
        private MimeReader(MimeEntity entity, Queue<string> lines)
            : this()
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }

            if (lines == null)
            {
                throw new ArgumentNullException("lines");
            }

            _lines = lines;
            _entity = new MimeEntity(entity);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="MimeReader"/> class.
        /// </summary>
        /// <param name="lines">The lines.</param>
        public MimeReader(string[] lines)
            : this()
        {
            if (lines == null)
            {
                throw new ArgumentNullException("lines");
            }

            _lines = new Queue<string>(lines);
        }

        /// <summary>
        /// Parse headers into _entity.Headers NameValueCollection.
        /// </summary>
        private int ParseHeaders()
        {
            string lastHeader = string.Empty;
            string line = string.Empty;
            // the first empty line is the end of the headers.
            while (_lines.Count > 0 && !string.IsNullOrEmpty(_lines.Peek()))
            {
                line = _lines.Dequeue();

                //if a header line starts with a space or tab then it is a continuation of the
                //previous line.
                if (line.StartsWith(" ") || line.StartsWith(Convert.ToString('\t')))
                {
                    _entity.Headers[lastHeader] = string.Concat(_entity.Headers[lastHeader], line);
                    continue;
                }

                int separatorIndex = line.IndexOf(':');

                if (separatorIndex < 0)
                {
                    System.Diagnostics.Debug.WriteLine("Invalid header:{0}", line);
                    continue;
                }  //This is an invalid header field.  Ignore this line.

                string headerName = line.Substring(0, separatorIndex);
                string headerValue = line.Substring(separatorIndex + 1).Trim(HeaderWhitespaceChars);

                _entity.Headers.Add(headerName.ToLower(), headerValue);
                lastHeader = headerName;
            }

            if (_lines.Count > 0)
            {
                _lines.Dequeue();
            } //remove closing header CRLF.

            return _entity.Headers.Count;
        }

        /// <summary>
        /// Processes mime specific headers.
        /// </summary>
        /// <returns>A mime entity with mime specific headers parsed.</returns>
        private void ProcessHeaders()
        {
            foreach (string key in _entity.Headers.AllKeys)
            {
                switch (key)
                {
                    case "content-description":
                        _entity.ContentDescription = _entity.Headers[key];
                        break;
                    case "content-disposition":
                        _entity.ContentDisposition = new ContentDisposition(_entity.Headers[key]);
                        break;
                    case "content-id":
                        _entity.ContentId = _entity.Headers[key];
                        break;
                    case "content-transfer-encoding":
                        _entity.TransferEncoding = _entity.Headers[key];
                        _entity.ContentTransferEncoding = MimeReader.GetTransferEncoding(_entity.Headers[key]);
                        break;
                    case "content-type":
                        _entity.SetContentType(MimeReader.GetContentType(_entity.Headers[key]));
                        break;
                    case "mime-version":
                        _entity.MimeVersion = _entity.Headers[key];
                        break;
                }
            }
        }

        /// <summary>
        /// Creates the MIME entity.
        /// </summary>
        /// <returns>A mime entity containing 0 or more children representing the mime message.</returns>
        public MimeEntity CreateMimeEntity()
        {
            try
            {
                ParseHeaders();

                ProcessHeaders();

                ParseBody();

                SetDecodedContentStream();

                return _entity;
            }
            catch
            {
                return null;

            }
        }


        /// <summary>
        /// Sets the decoded content stream by decoding the EncodedMessage 
        /// and writing it to the entity content stream.
        /// </summary>
        /// <param name="entity">The entity containing the encoded message.</param>
        private void SetDecodedContentStream()
        {
            switch (_entity.ContentTransferEncoding)
            {
                case System.Net.Mime.TransferEncoding.Base64:
                    _entity.Content = new MemoryStream(Convert.FromBase64String(_entity.EncodedMessage.ToString()), false);
                    break;

                case System.Net.Mime.TransferEncoding.QuotedPrintable:
                    _entity.Content = new MemoryStream(GetBytes(QuotedPrintableEncoding.Decode(_entity.EncodedMessage.ToString())), false);
                    break;

                case System.Net.Mime.TransferEncoding.SevenBit:
                default:
                    _entity.Content = new MemoryStream(GetBytes(_entity.EncodedMessage.ToString()), false);
                    break;
            }
        }

        /// <summary>
        /// Gets a byte[] of content for the provided string.
        /// </summary>
        /// <param name="decodedContent">Content.</param>
        /// <returns>A byte[] containing content.</returns>
        private byte[] GetBytes(string content)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    writer.Write(content);
                }
                return stream.ToArray();
            }
        }

        /// <summary>
        /// Parses the body.
        /// </summary>
        private void ParseBody()
        {
            if (_entity.HasBoundary)
            {
                while (_lines.Count > 0
                    && !string.Equals(_lines.Peek(), _entity.EndBoundary))
                {
                    /*Check to verify the current line is not the same as the parent starting boundary.  
                       If it is the same as the parent starting boundary this indicates existence of a 
                       new child entity. Return and process the next child.*/
                    if (_entity.Parent != null
                        && string.Equals(_entity.Parent.StartBoundary, _lines.Peek()))
                    {
                        return;
                    }

                    if (string.Equals(_lines.Peek(), _entity.StartBoundary))
                    {
                        AddChildEntity(_entity, _lines);
                    } //Parse a new child mime part.
                    else if (string.Equals(_entity.ContentType.MediaType, MediaTypes.MessageRfc822, StringComparison.InvariantCultureIgnoreCase)
                        && string.Equals(_entity.ContentDisposition.DispositionType, DispositionTypeNames.Attachment, StringComparison.InvariantCultureIgnoreCase))
                    {
                        /*If the content type is message/rfc822 the stop condition to parse headers has already been encountered.
                         But, a content type of message/rfc822 would have the message headers immediately following the mime
                         headers so we need to parse the headers for the attached message now.  This is done by creating
                         a new child entity.*/
                        AddChildEntity(_entity, _lines);

                        break;
                    }
                    else
                    {
                        _entity.EncodedMessage.Append(string.Concat(_lines.Dequeue(), Pop3Commands.Crlf));
                    } //Append the message content.
                }
            } //Parse a multipart message.
            else
            {
                while (_lines.Count > 0)
                {
                    _entity.EncodedMessage.Append(string.Concat(_lines.Dequeue(), Pop3Commands.Crlf));
                }
            } //Parse a single part message.
        }

        /// <summary>
        /// Adds the child entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        private void AddChildEntity(MimeEntity entity, Queue<string> lines)
        {
            /*if (entity == null)
            {
                return;
            }

            if (lines == null)
            {
                return;
            }*/

            MimeReader reader = new MimeReader(entity, lines);
            entity.Children.Add(reader.CreateMimeEntity());
        }

        /// <summary>
        /// Gets the type of the content.
        /// </summary>
        /// <param name="contentType">Type of the content.</param>
        /// <returns></returns>
        public static ContentType GetContentType(string contentType)
        {
            if (string.IsNullOrEmpty(contentType))
            {
                contentType = "text/plain; charset=us-ascii";
            }
            return new ContentType(contentType);

        }

        /// <summary>
        /// Gets the type of the media.
        /// </summary>
        /// <param name="mediaType">Type of the media.</param>
        /// <returns></returns>
        public static string GetMediaType(string mediaType)
        {
            if (string.IsNullOrEmpty(mediaType))
            {
                return "text/plain";
            }
            return mediaType.Trim();
        }

        /// <summary>
        /// Gets the type of the media main.
        /// </summary>
        /// <param name="mediaType">Type of the media.</param>
        /// <returns></returns>
        public static string GetMediaMainType(string mediaType)
        {
            int separatorIndex = mediaType.IndexOf('/');
            if (separatorIndex < 0)
            {
                return mediaType;
            }
            else
            {
                return mediaType.Substring(0, separatorIndex);
            }
        }

        /// <summary>
        /// Gets the type of the media sub.
        /// </summary>
        /// <param name="mediaType">Type of the media.</param>
        /// <returns></returns>
        public static string GetMediaSubType(string mediaType)
        {
            int separatorIndex = mediaType.IndexOf('/');
            if (separatorIndex < 0)
            {
                if (mediaType.Equals("text"))
                {
                    return "plain";
                }
                return string.Empty;
            }
            else
            {
                if (mediaType.Length > separatorIndex)
                {
                    return mediaType.Substring(separatorIndex + 1);
                }
                else
                {
                    string mainType = GetMediaMainType(mediaType);
                    if (mainType.Equals("text"))
                    {
                        return "plain";
                    }
                    return string.Empty;
                }
            }
        }

        /// <summary>
        /// Gets the transfer encoding.
        /// </summary>
        /// <param name="transferEncoding">The transfer encoding.</param>
        /// <returns></returns>
        /// <remarks>
        /// The transfer encoding determination follows the same rules as 
        /// Peter Huber's article w/ the exception of not throwing exceptions 
        /// when binary is provided as a transferEncoding.  Instead it is left
        /// to the calling code to check for binary.
        /// </remarks>
        public static TransferEncoding GetTransferEncoding(string transferEncoding)
        {
            switch (transferEncoding.Trim().ToLowerInvariant())
            {
                case "7bit":
                case "8bit":
                    return System.Net.Mime.TransferEncoding.SevenBit;
                case "quoted-printable":
                    return System.Net.Mime.TransferEncoding.QuotedPrintable;
                case "base64":
                    return System.Net.Mime.TransferEncoding.Base64;
                case "binary":
                default:
                    return System.Net.Mime.TransferEncoding.Unknown;

            }
        }
    }
}




1. 开通SVIP会员,免费下载本站所有源码,不限次数据,不限时间
2. 加官方QQ群,加官方微信群获取更多资源和帮助
3. 找站长苏飞做网站、商城、CRM、小程序、App、爬虫相关、项目外包等点这里
您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备18043678号-2)

GMT+8, 2025-4-20 10:54

© 2014-2021

快速回复 返回顶部 返回列表