发邮件界面:

收邮件界面:

先分析邮件发送类

邮件发送类使用smtp协议,这里以QQ邮箱为例

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Text;
  7. using System.Windows.Forms;
  8. //添加的命名空间引用
  9. using System.Net;
  10. using System.Net.Mail;
  11. using System.IO;
  12. using System.Net.Mime;
  13.  
  14. namespace SendMailExample
  15. {
  16. public partial class FormSendMail : Form
  17. {
  18. public FormSendMail()
  19. {
  20. InitializeComponent();
  21. }
  22.  
  23. private void FormSendMail_Load(object sender, EventArgs e)
  24. {
  25. //邮箱协议
  26. textBoxSmtpServer.Text = "smtp.qq.com";
  27. //发送人邮箱
  28. textBoxSend.Text = "邮箱账号";
  29. //发送人姓名
  30. textBoxDisplayName.Text = "名字";
  31. //密码
  32. textBoxPassword.Text = "邮箱密码";
  33. //收件人姓名
  34. textBoxReceive.Text = "收件人邮箱账号";
  35. //发送标题
  36. textBoxSubject.Text = "测试mytest";
  37. //发送内容
  38. textBoxBody.Text = "This is a test(测试)";
  39. radioButtonSsl.Checked = true;
  40. }
  41.  
  42. //单击【发送】按钮触发的事件
  43. private void buttonSend_Click(object sender, EventArgs e)
  44. {
  45. this.Cursor = Cursors.WaitCursor;
  46. //实例化一个发送邮件类
  47. MailMessage mailMessage = new MailMessage();
  48. //发件人邮箱,方法重载不同,可以根据需求自行选择
  49. mailMessage.From = new MailAddress(textBoxSend.Text, textBoxDisplayName.Text, System.Text.Encoding.UTF8);
  50. //收件人邮箱地址
  51. mailMessage.To.Add(textBoxReceive.Text);
  52. //邮件标题
  53. mailMessage.Subject = textBoxSubject.Text;
  54. //邮件发送使用的编码
  55. mailMessage.SubjectEncoding = System.Text.Encoding.Default;
  56. //邮件发送的内容
  57. mailMessage.Body = textBoxBody.Text;
  58. //发送邮件的标题
  59. mailMessage.BodyEncoding = System.Text.Encoding.Default;
  60. //指定邮件是否为html格式
  61. mailMessage.IsBodyHtml = false;
  62. //设置电子邮件的优先级
  63. mailMessage.Priority = MailPriority.Normal;
  64. //添加附件
  65. Attachment attachment = null;
  66. if (listBoxFileName.Items.Count > )
  67. {
  68. for (int i = ; i < listBoxFileName.Items.Count; i++)
  69. {
  70. string pathFileName = listBoxFileName.Items[i].ToString();
  71. string extName = Path.GetExtension(pathFileName).ToLower();
  72. //这里仅举例说明如何判断附件类型
  73. if (extName == ".rar" || extName == ".zip")
  74. {
  75. attachment = new Attachment(pathFileName, MediaTypeNames.Application.Zip);
  76. }
  77. else
  78. {
  79. attachment = new Attachment(pathFileName, MediaTypeNames.Application.Octet);
  80. }
  81. ContentDisposition cd = attachment.ContentDisposition;
  82. cd.CreationDate = File.GetCreationTime(pathFileName);
  83. cd.ModificationDate = File.GetLastWriteTime(pathFileName);
  84. cd.ReadDate = File.GetLastAccessTime(pathFileName);
  85. mailMessage.Attachments.Add(attachment);
  86. }
  87. }
  88. SmtpClient smtpClient = new SmtpClient();
  89. smtpClient.Host = textBoxSmtpServer.Text;
  90. smtpClient.Port = ;
  91. //是否使用安全套接字层加密连接
  92. smtpClient.EnableSsl = radioButtonSsl.Checked;
  93. //不使用默认凭证,注意此句必须放在client.Credentials的上面
  94. smtpClient.UseDefaultCredentials = false;
  95. smtpClient.Credentials = new NetworkCredential(textBoxSend.Text, textBoxPassword.Text);
  96. //邮件通过网络直接发送到服务器
  97. smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
  98. try
  99. {
  100. smtpClient.Send(mailMessage);
  101. MessageBox.Show("发送成功");
  102. }
  103. catch (SmtpException smtpError)
  104. {
  105. MessageBox.Show("发送失败:" + smtpError.StatusCode
  106. + "\n\n" + smtpError.Message
  107. + "\n\n" + smtpError.StackTrace);
  108. }
  109. finally
  110. {
  111. mailMessage.Dispose();
  112. smtpClient = null;
  113. this.Cursor = Cursors.Default;
  114. }
  115. }
  116.  
  117. //单击【添加附件】按钮触发的事件
  118. private void buttonAddAttachment_Click(object sender, EventArgs e)
  119. {
  120. //提示用户打开一个文件夹
  121. OpenFileDialog myOpenFileDialog = new OpenFileDialog();
  122. myOpenFileDialog.CheckFileExists = true;
  123. //只接收有效的文件名
  124. myOpenFileDialog.ValidateNames = true;
  125. //允许一次选择多个文件作为附件
  126. myOpenFileDialog.Multiselect = true;
  127. myOpenFileDialog.ShowDialog();
  128. if (myOpenFileDialog.FileNames.Length > )
  129. {
  130. listBoxFileName.Items.AddRange(myOpenFileDialog.FileNames);
  131. }
  132. }
  133. }
  134. }

收邮件的代码:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Text;
  7. using System.Windows.Forms;
  8. //添加的命名空间引用
  9. using System.Net;
  10. using System.Net.Sockets;
  11. using System.IO;
  12. namespace ReceiveMailExample
  13. {
  14. public partial class FormReceiveMail : Form
  15. {
  16. private TcpClient tcpClient;
  17. private NetworkStream networkStream;
  18. private StreamReader sr;
  19. private StreamWriter sw;
  20. public FormReceiveMail()
  21. {
  22. InitializeComponent();
  23. textBoxPOP3Server.Text = "pop.qq.com";
  24. textBoxPassword.Text = "密码";
  25. textBoxUser.Text = "邮箱账号";
  26. }
  27.  
  28. //单击建立连接按钮触发的事件
  29. private void buttonConnect_Click(object sender, EventArgs e)
  30. {
  31. Cursor.Current = Cursors.WaitCursor;
  32. listBoxStatus.Items.Clear();
  33. try
  34. {
  35. //建立与POP3服务器的连接,使用默认端口110
  36. tcpClient = new TcpClient(textBoxPOP3Server.Text,);
  37. listBoxStatus.Items.Add("与pop3服务器连接成功");
  38. }
  39. catch
  40. {
  41. MessageBox.Show("与服务器连接失败");
  42. return;
  43. }
  44. string str;
  45. networkStream = tcpClient.GetStream();
  46. //得到输入流
  47. sr = new StreamReader(networkStream, Encoding.Default);
  48. //得到输出流
  49. sw = new StreamWriter(networkStream, Encoding.Default);
  50. sw.AutoFlush = true;
  51. //读取服务器回送的连接信息
  52. str = GetResponse();
  53. if (CheckResponse(str) == false) return;
  54. //向服务器发送用户名,请求确认
  55. SendToServer("USER " + textBoxUser.Text);
  56. str = GetResponse();
  57. if (CheckResponse(str) == false) return;
  58. //向服务器发送密码,请求确认
  59. SendToServer("PASS " + textBoxPassword.Text);
  60. str = GetResponse();
  61. if (CheckResponse(str) == false) return;
  62. //向服务器发送LIST命令,请求获取邮件总数和总字节数
  63. SendToServer("LIST");
  64. str = GetResponse();
  65. if (CheckResponse(str) == false) return;
  66. string[] splitString = str.Split(' ');
  67. //从字符串中取子串获取邮件总数
  68. int count = int.Parse(splitString[]);
  69. //判断邮箱中是否有邮件
  70. if (count > )
  71. {
  72. listBoxOperation.Items.Clear();
  73. groupBoxOperation.Text = "信箱中共有 " + splitString[] + " 封邮件";
  74. //向邮件列表框中添加邮件
  75. for (int i = ; i < count; i++)
  76. {
  77. str = GetResponse();
  78. splitString = str.Split(' ');
  79. listBoxOperation.Items.Add(string.Format(
  80. "第{0}封:{1}字节", splitString[], splitString[]));
  81. }
  82. listBoxOperation.SelectedIndex = ;
  83. //读出结束符
  84. str = GetResponse();
  85. //设置对应状态信息
  86. buttonRead.Enabled = true;
  87. buttonDelete.Enabled = true;
  88. }
  89. else
  90. {
  91. groupBoxOperation.Text = "信箱中没有邮件";
  92. buttonRead.Enabled = false;
  93. buttonDelete.Enabled = false;
  94. }
  95. buttonConnect.Enabled = false;
  96. buttonDisconnect.Enabled = true;
  97. Cursor.Current = Cursors.Default;
  98. }
  99.  
  100. private bool SendToServer(string str)
  101. {
  102. try
  103. {
  104. sw.WriteLine(str);
  105. sw.Flush();
  106. listBoxStatus.Items.Add("发送:" + str);
  107. return true;
  108. }
  109. catch (Exception err)
  110. {
  111. listBoxStatus.Items.Add("发送失败:" + err.Message);
  112. return false;
  113. }
  114. }
  115.  
  116. private string GetResponse()
  117. {
  118. string str = null;
  119. try
  120. {
  121. str = sr.ReadLine();
  122. if (str == null)
  123. {
  124. listBoxStatus.Items.Add("收到:null");
  125. }
  126. else
  127. {
  128. listBoxStatus.Items.Add("收到:" + str);
  129. if (str.StartsWith("-ERR"))
  130. {
  131. str = null;
  132. }
  133. }
  134. }
  135. catch (Exception ex)
  136. {
  137. listBoxStatus.Items.Add("接收失败:" + ex.Message);
  138. }
  139. return str;
  140. }
  141.  
  142. private bool CheckResponse(string responseString)
  143. {
  144. if (responseString == null)
  145. {
  146. return false;
  147. }
  148. else
  149. {
  150. if (responseString.StartsWith("+OK"))
  151. {
  152. return true;
  153. }
  154. else
  155. {
  156. return false;
  157. }
  158. }
  159. }
  160.  
  161. //单击断开连接按钮触发的事件
  162. private void buttonDisconnect_Click(object sender, EventArgs e)
  163. {
  164. SendToServer("QUIT");
  165. sr.Close();
  166. sw.Close();
  167. networkStream.Close();
  168. tcpClient.Close();
  169. listBoxOperation.Items.Clear();
  170. richTextBoxOriginalMail.Clear();
  171. listBoxStatus.Items.Clear();
  172. groupBoxOperation.Text = "邮件信息";
  173. buttonConnect.Enabled = true;
  174. buttonDisconnect.Enabled = false;
  175. }
  176.  
  177. //单击阅读信件按钮触发的事件
  178. private void buttonRead_Click(object sender, EventArgs e)
  179. {
  180. Cursor.Current = Cursors.WaitCursor;
  181. richTextBoxOriginalMail.Clear();
  182. string mailIndex = listBoxOperation.SelectedItem.ToString();
  183. mailIndex = mailIndex.Substring(, mailIndex.IndexOf("封") - );
  184. SendToServer("RETR " + mailIndex);
  185. string str = GetResponse();
  186. if (CheckResponse(str) == false) return;
  187. try
  188. {
  189. string receiveData = sr.ReadLine();
  190. if (receiveData.StartsWith("-ERR") == true)
  191. {
  192. listBoxStatus.Items.Add(receiveData);
  193. }
  194. else
  195. {
  196. while (receiveData != ".")
  197. {
  198. richTextBoxOriginalMail.AppendText(receiveData + "\r\n");
  199. receiveData = sr.ReadLine();
  200. }
  201. }
  202. }
  203. catch (InvalidOperationException err)
  204. {
  205. listBoxStatus.Items.Add("Error: " + err.ToString());
  206. }
  207. Cursor.Current = Cursors.Default;
  208. }
  209.  
  210. private void DecodeMailHeader(string mail)
  211. {
  212. string header = "";
  213. int pos = mail.IndexOf("\n\n");
  214. if (pos == -)
  215. {
  216. header = GetDecodedHeader(mail);
  217. }
  218. else
  219. {
  220. header = mail.Substring(, pos + );
  221. }
  222. //richTextBoxDecode.AppendText(GetDecodedHeader(header));
  223. }
  224.  
  225. private string GetDecodedHeader(string header)
  226. {
  227. StringBuilder s = new StringBuilder();
  228. s.AppendLine("Subject:" + GetEncodedValueString(header, "Subject: ", false));
  229. s.AppendLine("From:" + GetEncodedValueString(header, "From: ", false).Trim());
  230. s.AppendLine("To:" + GetEncodedValueString(header, "To: ", true).Trim());
  231. s.AppendLine("Date:" + GetDateTimeFromString(GetValueString(header, "Date: ", false, false)));
  232. s.AppendLine("Cc:" + GetEncodedValueString(header, "Cc: ", true).Trim());
  233. s.AppendLine("ContentType:" + GetValueString(header, "Content-Type: ", false, true));
  234. return s.ToString();
  235. }
  236.  
  237. /// <summary>
  238. /// 把时间转成字符串形式
  239. /// </summary>
  240. /// <param name="DateTimeString"></param>
  241. /// <returns></returns>
  242. private string GetDateTimeFromString(string DateTimeString)
  243. {
  244. if (DateTimeString == "")
  245. {
  246. return null;
  247. }
  248. try
  249. {
  250. string strDateTime;
  251. if (DateTimeString.IndexOf("+") != -)
  252. {
  253. strDateTime = DateTimeString.Substring(, DateTimeString.IndexOf("+"));
  254. }
  255. else if (DateTimeString.IndexOf("-") != -)
  256. {
  257. strDateTime = DateTimeString.Substring(, DateTimeString.IndexOf("-"));
  258. }
  259. else
  260. {
  261. strDateTime = DateTimeString;
  262. }
  263. DateTime dt = DateTime.Parse(strDateTime);
  264. return dt.ToString();
  265. }
  266. catch
  267. {
  268. return null;
  269. }
  270. }
  271.  
  272. private string GetEncodedValueString(string SourceString, string Key, bool SplitBySemicolon)
  273. {
  274. int j;
  275. string strValue;
  276. string strSource = SourceString.ToLower();
  277. string strReturn = "";
  278. j = strSource.IndexOf(Key.ToLower());
  279. if (j != -)
  280. {
  281. j += Key.Length;
  282. int kk = strSource.IndexOf("\n", j);
  283. strValue = SourceString.Substring(j, kk - j).TrimEnd();
  284. do
  285. {
  286. if (strValue.IndexOf("=?") != -)
  287. {
  288. if (SplitBySemicolon == true)
  289. {
  290. strReturn += ConvertStringEncodingFromBase64(strValue) + "; ";
  291. }
  292. else
  293. {
  294. strReturn += ConvertStringEncodingFromBase64(strValue);
  295. }
  296. }
  297. else
  298. {
  299. strReturn += strValue;
  300. }
  301. j += strValue.Length + ;
  302. if (strSource.IndexOf("\r\n", j) == -)
  303. {
  304. break;
  305. }
  306. else
  307. {
  308. strValue = SourceString.Substring(j, strSource.IndexOf("\r\n", j) - j).TrimEnd();
  309. }
  310. }
  311. while (strValue.StartsWith(" ") || strValue.StartsWith("\t"));
  312. }
  313. else
  314. {
  315. strReturn = "";
  316. }
  317. return strReturn;
  318. }
  319.  
  320. private string GetValueString(string SourceString, string Key, bool ContainsQuotationMarks, bool ContainsSemicolon)
  321. {
  322. int j;
  323. string strReturn;
  324. string strSource = SourceString.ToLower();
  325. j = strSource.IndexOf(Key.ToLower());
  326. if (j != -)
  327. {
  328. j += Key.Length;
  329. strReturn = SourceString.Substring(j, strSource.IndexOf("\n", j) - j).TrimStart().TrimEnd();
  330. if (ContainsSemicolon == true)
  331. {
  332. if (strReturn.IndexOf(";") != -)
  333. {
  334. strReturn = strReturn.Substring(, strReturn.IndexOf(";"));
  335. }
  336. }
  337. if (ContainsQuotationMarks == true)
  338. {
  339. int i = strReturn.IndexOf("\"");
  340. int k;
  341. if (i != -)
  342. {
  343. k = strReturn.IndexOf("\"", i + );
  344. if (k != -)
  345. {
  346. strReturn = strReturn.Substring(i + , k - i - );
  347. }
  348. else
  349. {
  350. strReturn = strReturn.Substring(i + );
  351. }
  352. }
  353. }
  354. return strReturn;
  355. }
  356. else
  357. {
  358. return "";
  359. }
  360. }
  361.  
  362. private string ConvertStringEncodingFromBase64(string SourceString)
  363. {
  364. try
  365. {
  366. if (SourceString.IndexOf("=?") == -)
  367. {
  368. return SourceString;
  369. }
  370. else
  371. {
  372. int i = SourceString.IndexOf("?");
  373. int j = SourceString.IndexOf("?", i + );
  374. int k = SourceString.IndexOf("?", j + );
  375. char chrTransEnc = SourceString[j + ];
  376. switch (chrTransEnc)
  377. {
  378. case 'B':
  379. return ConvertStringEncodingFromBase64Ex(SourceString.Substring(k + , SourceString.IndexOf("?", k + ) - k - ), SourceString.Substring(i + , j - i - ));
  380. default:
  381. throw new Exception("unhandled content transfer encoding");
  382. }
  383. }
  384. }
  385. catch
  386. {
  387. return "";
  388. }
  389. }
  390.  
  391. /// <summary>
  392. /// 把Base64编码转换成字符串
  393. /// </summary>
  394. /// <param name="SourceString"></param>
  395. /// <param name="Charset"></param>
  396. /// <returns></returns>
  397. private string ConvertStringEncodingFromBase64Ex(string SourceString, string Charset)
  398. {
  399. try
  400. {
  401. Encoding enc;
  402. if (Charset == "")
  403. enc = Encoding.Default;
  404. else
  405. enc = Encoding.GetEncoding(Charset);
  406.  
  407. return enc.GetString(Convert.FromBase64String(SourceString));
  408. }
  409. catch
  410. {
  411. return "";
  412. }
  413. }
  414.  
  415. /// <summary>
  416. /// 把字符串转换成Base64Ex编码
  417. /// </summary>
  418. /// <param name="SourceString"></param>
  419. /// <param name="Charset"></param>
  420. /// <param name="AutoWordWrap"></param>
  421. /// <returns></returns>
  422. private string ConvertStringEncodingToBase64Ex(string SourceString, string Charset, bool AutoWordWrap)
  423. {
  424. Encoding enc = Encoding.GetEncoding(Charset);
  425. byte[] buffer = enc.GetBytes(SourceString);
  426. string strContent = Convert.ToBase64String(buffer);
  427. StringBuilder strTemp = new StringBuilder();
  428. int ii = ;
  429. for (int i = ; i <= strContent.Length / - ; i++)
  430. {
  431. strTemp.Append(strContent.Substring( * i, ) + "\r\n");
  432. ii++;
  433. }
  434. strTemp.Append(strContent.Substring( * (ii)));
  435. strContent = strTemp.ToString();
  436.  
  437. return strContent;
  438. }
  439.  
  440. private string ConvertStringEncoding(string SourceString, string Charset)
  441. {
  442. try
  443. {
  444. Encoding enc;
  445. if (Charset == "8bit" || Charset == "")
  446. {
  447. enc = Encoding.Default;
  448. }
  449. else
  450. {
  451. enc = Encoding.GetEncoding(Charset);
  452. }
  453. return enc.GetString(Encoding.ASCII.GetBytes(SourceString));
  454. }
  455. catch
  456. {
  457. return Encoding.Default.GetString(Encoding.ASCII.GetBytes(SourceString));
  458. }
  459. }
  460.  
  461. //单击删除信件按钮触发的事件
  462. private void buttonDelete_Click(object sender, EventArgs e)
  463. {
  464. string parameter = listBoxOperation.SelectedItem.ToString();
  465. parameter = parameter.Substring(, parameter.IndexOf("封") - );
  466. SendToServer("DELE " + parameter);
  467. string str = GetResponse();
  468. if (CheckResponse(str) == false) return;
  469. richTextBoxOriginalMail.Clear();
  470. int j = listBoxOperation.SelectedIndex;
  471. listBoxOperation.Items.Remove(listBoxOperation.Items[j].ToString());
  472. MessageBox.Show("删除成功");
  473. }
  474. }
  475. }

C#开发邮件收发(同步)的更多相关文章

  1. 用SugarORM快速开发需要同步和保存大量数据的Android互联网客户端

    最近开发的一个项目主要有两个特点,这两点也是在项目开发前需要着重去规划解决方案的: 需要和Rest服务端请求大量的数据 同时这些数据本地也要保存到sqlite数据库 对于第一点,目前的Volley.G ...

  2. Linux驱动开发5——同步机制

    上一章讲到了并发,指的是多个进程同时存取临界区资源的处理机制.这一章讲的同步机制,讲的是多个进程之间协同工作的处理机制,如临界区数据还没有准备好,A进程负责准备数据,B进程等待A进程完成之后读取数据. ...

  3. iOS开发线程同步技术-锁

    概览 1,什么是锁(临界区)? 2,常用的锁有哪些? 3,相关链接 什么是锁(临界区) 临界区:指的是一块对公共资源进行访问的代码,并非一种机制或是算法. 常用的锁有哪些? 互斥锁:是一种用于多线程编 ...

  4. C#多线程开发-线程同步 02

    上一篇文章主要带领大家认识了线程,也了解到了线程的基本用法和状态,接下来就让我们一起学习下什么是线程同步. 线程中异常的处理 在线程中始终使用try/catch代码块是非常重要的,因为不可能在线程代码 ...

  5. java开发常用jar包介绍(转载)

    jta.jar 标准JTA API必要 commons-collections.jar 集合类 必要 antlr.jar  ANother Tool for Language Recognition ...

  6. laravel下的团队开发

    当你的团队在开发一个大型应用时,该应用的不同部分可能以不同的速度前进.比如,设想下面的场景:一个开发热源被分配 数据层 的backend工作,而另外一个开发人员做front-end和web/contr ...

  7. ios程序开发杂记

    ios程序开发杂记 一.程序构建 与一般的程序构建无太大区别,都是源文件编译链接这一套,通常是在mac上做交叉编译,也就是利用xcode里带的ios编译工具集去生成arm架构的ios程序(或是x86的 ...

  8. .NET软件开发与常用工具清单

    [工欲善其事,必先利其器]软件开发的第一步就是选择高效.智能的工具. 下面列出的工具软件能辅助提高工作效率.  开发类工具 微软.Net平台下的集成开发环境:Visual Studio. Visual ...

  9. ACE框架 同步原语设计

    ACE框架常用的同步机制设计成统一的原语接口.同步原语使用系统平台(操作系统,多线程库)提供的同步原语,并为系统平台不提供的同步原语提供模拟实现.ACE框架使用了外观模式和适配器分两层,将同步原语统一 ...

随机推荐

  1. paxos 练手 推进中

    学习https://github.com/huoyu820125/SecondPaxos 自己编写网络版本 在学习过程将此代码的线程 锁等改成c++11  就不用包含那么多文件 主要更改如下 // M ...

  2. Vue 全家桶介绍

    Vue有著名的全家桶系列,包含了vue-router(http://router.vuejs.org),vuex(http://vuex.vuejs.org), vue-resource(https: ...

  3. js 异步加载和同步加载

    异步加载 异步加载也叫非阻塞模式加载,浏览器在下载js的同时,同时还会执行后续的页面处理.在script标签内,用js创建一个script元素并插入到document中,这种就是异步加载js文件了: ...

  4. 别人的Linux私房菜(2)Linux简介

    同一操作系统无法在不同硬件平台上运行.架构. Bell实验室和麻省理工学院MIT和通用电气公司GE发起了Multics计划,分时兼容系统,300以上多终端连接主机. Unics 由Multics中的人 ...

  5. fastq-to-fasta转换及fasta拆分、合并

    格式转换: use awk :awk 'BEGIN{P=1}{if(P==1||P==2){gsub(/^[@]/,">");print}; if(P==4)P=0; P++ ...

  6. jquery特殊字符转义方法

    //特殊字符转义function escapeJquery(srcString) { // 转义之后的结果 var escapseResult = srcString; // javascript正则 ...

  7. 【转载】Impala和Hive的区别

    Impala和Hive的关系  Impala是基于Hive的大数据实时分析查询引擎,直接使用Hive的元数据库Metadata,意味着impala元数据都存储在Hive的metastore中.并且im ...

  8. myeclipse cannot connect to vm

    启动tomcat时,tomcat可以直接运行,而debug时弹出 解决方法:打开360安全卫士的功能大全找到修复网络(LSP)点击立即修复就可以使用debug

  9. 学以致用十七-----shell脚本之比较数字和字符串及if else

    非常需要注意的是shell脚本对空格要求非常严格, 如: 比较字符串   (不能用于比较字符串) 以上这种写法会报错 因此比较字符串不用 单中括号 [ ] -----------------有误 而是 ...

  10. struts1(一)流程分析