﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Titan专栏-文章分类-Java技术</title><link>http://www.blogjava.net/Titan/category/5789.html</link><description>用文字来整理生命</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 14:32:57 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 14:32:57 GMT</pubDate><ttl>60</ttl><item><title>使用javamail发送html邮件</title><link>http://www.blogjava.net/Titan/articles/30523.html</link><dc:creator>Titan</dc:creator><author>Titan</author><pubDate>Mon, 13 Feb 2006 14:34:00 GMT</pubDate><guid>http://www.blogjava.net/Titan/articles/30523.html</guid><wfw:comment>http://www.blogjava.net/Titan/comments/30523.html</wfw:comment><comments>http://www.blogjava.net/Titan/articles/30523.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Titan/comments/commentRss/30523.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Titan/services/trackbacks/30523.html</trackback:ping><description><![CDATA[<P>使用javamail发送html邮件比较复杂</P>
<P>package org.tatan.mail;</P>
<P>import javax.mail.internet.InternetAddress;<BR>import javax.mail.internet.MimeMessage;<BR>import javax.mail.internet.MimeUtility;<BR>import javax.mail.Session;<BR>import javax.mail.MessagingException;<BR>import javax.mail.Transport;</P>
<P>public class SendHtmlMail {<BR>&nbsp;&nbsp;&nbsp; public static void sendMessage(String smtpHost,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String from, String to,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String subject, String messageText)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws MessagingException,java.io.UnsupportedEncodingException {</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Step 1:&nbsp; Configure the mail session<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Configuring mail session for: " + smtpHost);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.util.Properties props = new java.util.Properties();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; props.setProperty("mail.smtp.auth", "true");//指定是否需要SMTP验证<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; props.setProperty("mail.smtp.host", smtpHost);//指定SMTP服务器<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; props.put("mail.transport.protocol", "smtp");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Session mailSession = Session.getDefaultInstance(props);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mailSession.setDebug(true);//是否在控制台显示debug信息</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Step 2:&nbsp; Construct the message<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Constructing message -&nbsp; from=" + from + "&nbsp; to=" + to);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InternetAddress fromAddress = new InternetAddress(from);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InternetAddress toAddress = new InternetAddress(to);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MimeMessage testMessage = new MimeMessage(mailSession);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; testMessage.setFrom(fromAddress);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; testMessage.addRecipient(javax.mail.Message.RecipientType.TO, toAddress);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; testMessage.setSentDate(new java.util.Date());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; testMessage.setSubject(MimeUtility.encodeText(subject,"gb2312","B"));</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; testMessage.setContent(messageText, "text/html;charset=gb2312");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Message constructed");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Step 3:&nbsp; Now send the message<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transport transport = mailSession.getTransport("smtp");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; transport.connect(smtpHost, "webmaster", "password");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; transport.sendMessage(testMessage, testMessage.getAllRecipients());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; transport.close();</P>
<P><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Message sent!");<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; public static void main(String[] args) {</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String smtpHost = "localhost";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String from = "<A href="mailto:webmaster@mymail.com">webmaster@mymail.com</A>";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String to = "<A href="mailto:mfc42d@sohu.com">mfc42d@sohu.com</A>";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String subject = "html邮件测试"; //subject javamail自动转码</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StringBuffer theMessage = new StringBuffer();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; theMessage.append("&lt;h2&gt;&lt;font color=red&gt;这倒霉孩子&lt;/font&gt;&lt;/h2&gt;");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; theMessage.append("&lt;hr&gt;");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; theMessage.append("&lt;i&gt;年年失望年年望&lt;/i&gt;");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SendHtmlMail.sendMessage(smtpHost, from, to, subject, theMessage.toString());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (javax.mail.MessagingException exc) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exc.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (java.io.UnsupportedEncodingException exc) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exc.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>}<BR>邮件头(参见RFC822，RFC2047)只能包含US-ASCII字符。<BR>邮件头中任何包含非US-ASCII字符的部分必须进行编码，使其只包含US-ASCII字符。<BR>但是java mail可以根据JVM发送中文邮件自行编码，，用它自带的MimeUtility类的encodeText方法对中文信息进行编码也可以。<BR>邮件正文必须有charset=gb2312否则为<BR>Content-Type: text/html; charset=us-ascii<BR>Content-Transfer-Encoding: 7bit<BR>打开邮件为乱码,设置charset=gb2312后<BR>Content-Type: text/html;charset=gb2312<BR>Content-Transfer-Encoding: quoted-printable<BR>它不能用MimeUtility里的方法来编码。<BR>邮件正文的编码方式的信息是要放在Content-Transfer-Encoding这个邮件头参数中的，<BR>而MimeUtility里面的方法是将编码方式的信息放在编码后的正文内容中。<BR>所以如果你对正文也用MimeUtility进行处理，那么其他邮件程序就不会正常显示你编码的邮件，<BR>因为其他邮件软件如outlook,foxmail只会根据Content-Transfer-Encoding这个里面的信息来对邮件正文进行解码。</P><img src ="http://www.blogjava.net/Titan/aggbug/30523.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Titan/" target="_blank">Titan</a> 2006-02-13 22:34 <a href="http://www.blogjava.net/Titan/articles/30523.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>javamail发送带有附件的html邮件</title><link>http://www.blogjava.net/Titan/articles/30522.html</link><dc:creator>Titan</dc:creator><author>Titan</author><pubDate>Mon, 13 Feb 2006 14:32:00 GMT</pubDate><guid>http://www.blogjava.net/Titan/articles/30522.html</guid><wfw:comment>http://www.blogjava.net/Titan/comments/30522.html</wfw:comment><comments>http://www.blogjava.net/Titan/articles/30522.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Titan/comments/commentRss/30522.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Titan/services/trackbacks/30522.html</trackback:ping><description><![CDATA[<P>package org.tatan.mail;</P>
<P>import javax.mail.Session;<BR>import javax.mail.MessagingException;<BR>import javax.mail.Multipart;<BR>import javax.mail.Transport;<BR>import javax.mail.internet.InternetAddress;<BR>import javax.mail.internet.MimeMessage;<BR>import javax.mail.internet.MimeBodyPart;<BR>import javax.mail.internet.MimeMultipart;<BR>import javax.activation.FileDataSource;<BR>import javax.activation.DataHandler;</P>
<P><BR>public class SendAttachMail {<BR>&nbsp;&nbsp;&nbsp; public static void sendMessage(String smtpHost,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String from, String to,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String subject, String messageText,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String fileName)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws MessagingException {</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Step 1:&nbsp; Configure the mail session<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.util.Properties props = new java.util.Properties();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; props.setProperty("mail.smtp.auth", "true");//指定是否需要SMTP验证<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; props.setProperty("mail.smtp.host", smtpHost);//指定SMTP服务器<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; props.put("mail.transport.protocol", "smtp");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Session mailSession = Session.getDefaultInstance(props);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mailSession.setDebug(true);//是否在控制台显示debug信息</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Step 2:&nbsp; Construct the message<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Constructing message -&nbsp; from=" + from + "&nbsp; to=" + to);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InternetAddress fromAddress = new InternetAddress(from);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InternetAddress toAddress = new InternetAddress(to);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MimeMessage testMessage = new MimeMessage(mailSession);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; testMessage.setFrom(fromAddress);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; testMessage.addRecipient(javax.mail.Message.RecipientType.TO, toAddress);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; testMessage.setSentDate(new java.util.Date());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; testMessage.setSubject(subject);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp; Step 3:&nbsp; Create a body part to hold the "text" portion of the message<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Constructing 'text' body part");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MimeBodyPart textBodyPart = new MimeBodyPart();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; textBodyPart.setContent(messageText,"text/html;charset=gb2312");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp; Step 4:&nbsp; Create a body part to hold the "file" portion of the message<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Attaching 'file' body part: " + fileName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MimeBodyPart fileBodyPart = new MimeBodyPart();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileDataSource fds = new FileDataSource("c:\\a.rar");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fileBodyPart.setDataHandler(new DataHandler(fds));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fileBodyPart.setFileName(fds.getName());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Finished attaching file");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Step 5:&nbsp; Create a Multipart/container and add the parts<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Multipart container = new MimeMultipart();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; container.addBodyPart(textBodyPart);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; container.addBodyPart(fileBodyPart);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Step 6:&nbsp; Add the Multipart to the actual message<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; testMessage.setContent(container);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Message constructed");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Step 7:&nbsp; Now send the message<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transport transport = mailSession.getTransport("smtp");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; transport.connect(smtpHost, "webmaster", "password");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; transport.sendMessage(testMessage, testMessage.getAllRecipients());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; transport.close();</P>
<P><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Message sent!");<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; public static void main(String[] args) {</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String fileName = "a.rar";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String smtpHost = "localhost";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String from = "<A href="mailto:webmaster@mymail.com">webmaster@mymail.com</A>";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String to = "<A href="mailto:mfc42d@sohu.com">mfc42d@sohu.com</A>";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String subject = "html邮件附件测试"; //subject javamail自动转码<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StringBuffer theMessage = new StringBuffer();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; theMessage.append("&lt;h2&gt;&lt;font color=red&gt;这倒霉孩子&lt;/font&gt;&lt;/h2&gt;");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; theMessage.append("&lt;hr&gt;");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; theMessage.append("&lt;i&gt;年年失望年年望&lt;/i&gt;");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SendAttachMail.sendMessage(smtpHost, from, to, subject, theMessage.toString(), fileName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (javax.mail.MessagingException exc) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exc.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>}<BR></P><img src ="http://www.blogjava.net/Titan/aggbug/30522.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Titan/" target="_blank">Titan</a> 2006-02-13 22:32 <a href="http://www.blogjava.net/Titan/articles/30522.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>执行的Runtime类调用程序停掉的原因</title><link>http://www.blogjava.net/Titan/articles/30521.html</link><dc:creator>Titan</dc:creator><author>Titan</author><pubDate>Mon, 13 Feb 2006 14:30:00 GMT</pubDate><guid>http://www.blogjava.net/Titan/articles/30521.html</guid><wfw:comment>http://www.blogjava.net/Titan/comments/30521.html</wfw:comment><comments>http://www.blogjava.net/Titan/articles/30521.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Titan/comments/commentRss/30521.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Titan/services/trackbacks/30521.html</trackback:ping><description><![CDATA[<P>牛牛发现问题的原因，Process&nbsp; process=Runtime.getRuntime().exec("");中产生停滞（阻塞，blocking）。</P>
<P>这个是因为Runtime.getRuntime().exec()要自己去处理stdout和stderr的。&nbsp; <BR>所以如果你想让程序正常运行的话，请务必将上述用别的线程流取走。&nbsp; <BR>&nbsp;<BR>&gt;test.bat&nbsp; <BR>haha&nbsp; <BR>exit&nbsp; 99&nbsp; <BR>&nbsp;<BR>&gt;RuntimeTest.java&nbsp; <BR>public&nbsp; class&nbsp; RuntimeTest&nbsp; {&nbsp; <BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public&nbsp; static&nbsp; void&nbsp; main(String[]&nbsp; args)&nbsp; {&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try&nbsp; {&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Process&nbsp; process=Runtime.getRuntime().exec("test.bat");&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StreamGobbler&nbsp; errorGobbler&nbsp; =&nbsp; new&nbsp; StreamGobbler(process.getErrorStream(),&nbsp; "ERROR");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp; kick&nbsp; off&nbsp; stderr&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; errorGobbler.start();&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StreamGobbler&nbsp; outGobbler&nbsp; =&nbsp; new&nbsp; StreamGobbler(process.getInputStream(),&nbsp; "STDOUT");&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp; kick&nbsp; off&nbsp; stdout&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outGobbler.start();&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; process.waitFor();&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(process.exitValue());&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; catch(Exception&nbsp; e)&nbsp; {}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <BR>}&nbsp; <BR>&nbsp;<BR>&nbsp;<BR>&gt;StreamGobbler.java&nbsp; <BR>import&nbsp; java.io.BufferedReader;&nbsp; <BR>import&nbsp; java.io.IOException;&nbsp; <BR>import&nbsp; java.io.InputStream;&nbsp; <BR>import&nbsp; java.io.InputStreamReader;&nbsp; <BR>import&nbsp; java.io.OutputStream;&nbsp; <BR>import&nbsp; java.io.PrintWriter;&nbsp; <BR>&nbsp;<BR>public&nbsp; class&nbsp; StreamGobbler&nbsp; extends&nbsp; Thread&nbsp; {&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputStream&nbsp; is;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String&nbsp; type;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OutputStream&nbsp; os;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StreamGobbler(InputStream&nbsp; is,&nbsp; String&nbsp; type)&nbsp; {&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this(is,&nbsp; type,&nbsp; null);&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StreamGobbler(InputStream&nbsp; is,&nbsp; String&nbsp; type,&nbsp; OutputStream&nbsp; redirect)&nbsp; {&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.is&nbsp; =&nbsp; is;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.type&nbsp; =&nbsp; type;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.os&nbsp; =&nbsp; redirect;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public&nbsp; void&nbsp; run()&nbsp; {&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try&nbsp; {&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PrintWriter&nbsp; pw&nbsp; =&nbsp; null;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if&nbsp; (os&nbsp; !=&nbsp; null)&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pw&nbsp; =&nbsp; new&nbsp; PrintWriter(os);&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputStreamReader&nbsp; isr&nbsp; =&nbsp; new&nbsp; InputStreamReader(is);&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BufferedReader&nbsp; br&nbsp; =&nbsp; new&nbsp; BufferedReader(isr);&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String&nbsp; line=null;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while&nbsp; (&nbsp; (line&nbsp; =&nbsp; br.readLine())&nbsp; !=&nbsp; null)&nbsp; {&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if&nbsp; (pw&nbsp; !=&nbsp; null)&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pw.println(line);&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(type&nbsp; +&nbsp; "&gt;"&nbsp; +&nbsp; line);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if&nbsp; (pw&nbsp; !=&nbsp; null)&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pw.flush();&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; catch&nbsp; (IOException&nbsp; ioe)&nbsp; {&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ioe.printStackTrace();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <BR>}<BR>自己mark一下</P>
<P><A href="http://blogger.org.cn/blog/more.asp?name=hongrui&amp;id=9734"><STRONG><FONT size=4></FONT></STRONG></A>&nbsp;</P><img src ="http://www.blogjava.net/Titan/aggbug/30521.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Titan/" target="_blank">Titan</a> 2006-02-13 22:30 <a href="http://www.blogjava.net/Titan/articles/30521.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java语言对时间的处理</title><link>http://www.blogjava.net/Titan/articles/30520.html</link><dc:creator>Titan</dc:creator><author>Titan</author><pubDate>Mon, 13 Feb 2006 14:27:00 GMT</pubDate><guid>http://www.blogjava.net/Titan/articles/30520.html</guid><wfw:comment>http://www.blogjava.net/Titan/comments/30520.html</wfw:comment><comments>http://www.blogjava.net/Titan/articles/30520.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Titan/comments/commentRss/30520.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Titan/services/trackbacks/30520.html</trackback:ping><description><![CDATA[<P>1.处理数据库，有DATE Java.sql.Date 日期，<BR>TIME Java.sql.Time 时戳，TIMESTAMP Java.sql.Timestamp 当日日期和时间，<BR>对应的ResultSet的方法<BR>DATE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.sql.Date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.sql.Date getDate()<BR>TIME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.sql.Time&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.sql.Time getTime()<BR>TIMESTAMP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.sql.Timestamp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.sql.Timestamp getTimestamp()<BR>根据java2的规范要求使用Java.sql.Timestamp，这样不会失去精度详见（<A href="http://blogger.org.cn/blog/more.asp?name=hongrui&amp;id=7557">http://blogger.org.cn/blog/more.asp?name=hongrui&amp;id=7557</A>）。对于oracle数据库比较例外，可以用oracle.sql.TIMESTAMP<BR>这和他的版本也有关系。<FONT color=#f73809>注意，SQLserver中timestamp 对应的是 DateTime类型。<BR></FONT>使用spring的jdbc时，尽可能用Java.sql.Timestamp详见（<A href="http://blogger.org.cn/blog/more.asp?name=hongrui&amp;id=9521">http://blogger.org.cn/blog/more.asp?name=hongrui&amp;id=9521</A>）。<BR>下面给个例子<BR>public static java.sql.Timestamp getDBSysdate(Connection conn)<BR>throws Exception {<BR>Statement stmt = null;<BR>ResultSet rs = null;<BR>Timestamp sysTime = null;</P>
<P>try {<BR>stmt = conn.createStatement();<BR>rs = stmt.executeQuery("SELECT SYSDATE FROM DUAL");<BR>if (rs.next()) {<BR>sysTime = rs.getTimestamp("SYSDATE");<BR>}<BR>} catch (Exception e) {</P>
<P>} finally {<BR>try {<BR>if (rs != null) {<BR>rs.close();<BR>}<BR>if (stmt != null) {<BR>stmt.close();<BR>}<BR>} catch (Exception e) {</P>
<P>}<BR>}</P>
<P>return sysTime;<BR>}<BR><FONT color=#f76809>最好的办法使用long存时间，使用Calendar 处理，就是表示日期时间不直观。<BR></FONT>2.<FONT color=#f70968>字符串转化时间，注意不能判断时间输入是否正确，判断时间输入是否正确，请使用正则。<BR></FONT>try<BR>&nbsp;&nbsp;&nbsp; &nbsp;{ <BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;String st="2005-13-32 12:00";<BR>&nbsp;&nbsp;&nbsp; &nbsp;java.text.DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm");<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date&nbsp; starttime = df.parse(st);<BR>&nbsp;&nbsp;&nbsp; &nbsp;System.out.println(starttime.toString());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; &nbsp;} <BR>catch(Exception ex)<BR>{<BR>&nbsp;<BR>}<BR>不要搞混了try-catch的功能。只有程序或系统抛出了异常，try-catch才能捕获 ，得到Wed Feb 01 00:00:00 CST 2006<BR>这样操作是错误的，Timestamp是java.util.Date，会得到java.lang.ClassCastException，你犯了向下转型的错误。</P>
<P>try<BR>&nbsp;&nbsp;&nbsp; &nbsp;{ <BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;String st="2005-13-32 12:00";<BR>&nbsp;&nbsp;&nbsp; &nbsp;java.text.DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm");<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Timestamp&nbsp; starttime =(Timestamp) df.parse(st);<BR>&nbsp;&nbsp;&nbsp; &nbsp;System.out.println(starttime.toString());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; &nbsp;} <BR>catch(Exception ex)<BR>{<BR>&nbsp;ex.printStackTrace();<BR>}<BR>应该使用<BR>try {<BR>&nbsp;&nbsp;&nbsp;String st = "2005-12-2 12:00:00";<BR>&nbsp;&nbsp;&nbsp;Timestamp starttime = Timestamp.valueOf(st);<BR>&nbsp;&nbsp;&nbsp;System.out.println(starttime.toString());<BR>&nbsp;&nbsp;} catch (Exception ex) {<BR>&nbsp;&nbsp;&nbsp;ex.printStackTrace();<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;或<BR>&nbsp;&nbsp;import java.sql.*;<BR>import java.util.*;</P>
<P>public class CreateTimestamp {<BR>&nbsp;&nbsp; public static void main(String [] args) {</P>
<P>&nbsp;&nbsp; Calendar cal = Calendar.getInstance();</P>
<P>&nbsp;&nbsp; cal.set(Calendar.YEAR, 2000);<BR>&nbsp;&nbsp; cal.set(Calendar.MONTH, Calendar.JANUARY);<BR>&nbsp;&nbsp; cal.set(Calendar.DATE, 1);<BR>&nbsp;&nbsp; cal.set(Calendar.HOUR_OF_DAY, 11);<BR>&nbsp;&nbsp; cal.set(Calendar.MINUTE, 45);<BR>&nbsp;&nbsp; cal.set(Calendar.SECOND, 30);<BR>&nbsp;&nbsp; cal.set(Calendar.MILLISECOND, 0);</P>
<P>&nbsp;&nbsp; long millis = cal.getTime().getTime();<BR>&nbsp;&nbsp; System.out.println("milliseconds in millis = " + millis);<BR>&nbsp;&nbsp; java.sql.Timestamp ts = new java.sql.Timestamp(millis);<BR>&nbsp;&nbsp; System.out.println("Timestamp ts before setting nanos = " + ts);</P>
<P>&nbsp;&nbsp; ts.setNanos(500);<BR>&nbsp;&nbsp; System.out.println("Timestamp ts with nanos set = " + ts);<BR>&nbsp;&nbsp; }<BR>}</P>
<P><BR>下面给出javadoc的方法<BR>1. java.sql.Date.valueOf(java.lang.String) </P>
<P>&nbsp;&nbsp;&nbsp; public static Date valueOf(String s)<BR>&nbsp;Converts a string in JDBC date escape format to a Date value. </P>
<P>&nbsp;Parameters:<BR>&nbsp;s - a String object representing a date in in the format "yyyy-mm-dd" <BR>&nbsp;Returns:<BR>&nbsp;a java.sql.Date object representing the given date <BR>&nbsp;Throws: <BR>&nbsp;IllegalArgumentException - if the date given is not in the JDBC date escape format (yyyy-mm-dd)</P>
<P>2. java.sql.Time.valueOf(java.lang.String) </P>
<P>&nbsp;&nbsp;&nbsp; public static Time valueOf(String s)<BR>&nbsp;Converts a string in JDBC time escape format to a Time value. </P>
<P>&nbsp;Parameters:<BR>&nbsp;s - time in format "hh:mm:ss" <BR>&nbsp;Returns:<BR>&nbsp;a corresponding Time object</P>
<P>3. java.sql.Timestamp.valueOf(java.lang.String) <BR>&nbsp;&nbsp; <BR>&nbsp;&nbsp; public static Timestamp valueOf(String s)<BR>&nbsp;Converts a String object in JDBC timestamp escape format to a Timestamp value. </P>
<P>&nbsp;Parameters:<BR>&nbsp;s - timestamp in format yyyy-mm-dd hh:mm:ss.fffffffff <BR>&nbsp;Returns:<BR>&nbsp;corresponding Timestamp value <BR>&nbsp;Throws: <BR>&nbsp;IllegalArgumentException - if the given argument does not have the format yyyy-mm-dd hh:mm:ss.fffffffff</P><img src ="http://www.blogjava.net/Titan/aggbug/30520.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Titan/" target="_blank">Titan</a> 2006-02-13 22:27 <a href="http://www.blogjava.net/Titan/articles/30520.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java如何计算两个日期之间相差的天数</title><link>http://www.blogjava.net/Titan/articles/30519.html</link><dc:creator>Titan</dc:creator><author>Titan</author><pubDate>Mon, 13 Feb 2006 14:25:00 GMT</pubDate><guid>http://www.blogjava.net/Titan/articles/30519.html</guid><wfw:comment>http://www.blogjava.net/Titan/comments/30519.html</wfw:comment><comments>http://www.blogjava.net/Titan/articles/30519.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Titan/comments/commentRss/30519.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Titan/services/trackbacks/30519.html</trackback:ping><description><![CDATA[<P>看完了jdk的help，发现sun没有提供这样的一个函数，朋友给了几个实现方法</P>
<P>//取得剩余天数<BR>&nbsp;&nbsp;&nbsp;SimpleDateFormat df=new SimpleDateFormat("yyyymmdd");<BR>&nbsp;&nbsp;&nbsp;Date d0=new java.util.Date();<BR>&nbsp;&nbsp;&nbsp;Date d1=df.parse(end_date);<BR>&nbsp;&nbsp;&nbsp;long time0=d0.getTime();<BR>&nbsp;&nbsp;&nbsp;long time1=d1.getTime();<BR>&nbsp;&nbsp;&nbsp;System.out.println((time1-time0)/(1000*60*60*24)); </P>
<P>这样算两个时间相差的天数比较好 </P>
<P>/**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 计算两个日期之间相差的天数<BR>&nbsp;&nbsp;&nbsp;&nbsp; * <BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param date1<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param date2<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @return<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public static int diffdates(Date date1, Date date2) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int result = 0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ElapsedTime et = new ElapsedTime();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar gc1 = new GregorianCalendar();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar gc2 = new GregorianCalendar();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc1.setTime(date1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc2.setTime(date2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = et.getDays(gc1, gc2);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return result;<BR>&nbsp;&nbsp;&nbsp; } <BR><BR>然后ElapseTime中的方法是：<BR>public int getDays(GregorianCalendar g1, GregorianCalendar g2) {<BR>&nbsp;&nbsp;int elapsed = 0;<BR>&nbsp;&nbsp;GregorianCalendar gc1, gc2;</P>
<P>&nbsp;&nbsp;if (g2.after(g1)) {<BR>&nbsp;&nbsp;&nbsp;gc2 = (GregorianCalendar) g2.clone();<BR>&nbsp;&nbsp;&nbsp;gc1 = (GregorianCalendar) g1.clone();<BR>&nbsp;&nbsp;} else {<BR>&nbsp;&nbsp;&nbsp;gc2 = (GregorianCalendar) g1.clone();<BR>&nbsp;&nbsp;&nbsp;gc1 = (GregorianCalendar) g2.clone();<BR>&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;gc1.clear(Calendar.MILLISECOND);<BR>&nbsp;&nbsp;gc1.clear(Calendar.SECOND);<BR>&nbsp;&nbsp;gc1.clear(Calendar.MINUTE);<BR>&nbsp;&nbsp;gc1.clear(Calendar.HOUR_OF_DAY);</P>
<P>&nbsp;&nbsp;gc2.clear(Calendar.MILLISECOND);<BR>&nbsp;&nbsp;gc2.clear(Calendar.SECOND);<BR>&nbsp;&nbsp;gc2.clear(Calendar.MINUTE);<BR>&nbsp;&nbsp;gc2.clear(Calendar.HOUR_OF_DAY);</P>
<P>&nbsp;&nbsp;while (gc1.before(gc2)) {<BR>&nbsp;&nbsp;&nbsp;gc1.add(Calendar.DATE, 1);<BR>&nbsp;&nbsp;&nbsp;elapsed++;<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;return elapsed;<BR>&nbsp;}<BR>其实使用<FONT size=2>joda最简单</FONT></P>
<P>public boolean isRentalOverdue(<B>DateTime</B> datetimeRented) {<BR>&nbsp; <B>Period</B> rentalPeriod = Period.days(2);<BR>&nbsp; return datetimeRented.plus(rentalPeriod).isBeforeNow()<BR>}<BR></P><img src ="http://www.blogjava.net/Titan/aggbug/30519.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Titan/" target="_blank">Titan</a> 2006-02-13 22:25 <a href="http://www.blogjava.net/Titan/articles/30519.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]正则表达式之道</title><link>http://www.blogjava.net/Titan/articles/28844.html</link><dc:creator>Titan</dc:creator><author>Titan</author><pubDate>Fri, 20 Jan 2006 15:58:00 GMT</pubDate><guid>http://www.blogjava.net/Titan/articles/28844.html</guid><wfw:comment>http://www.blogjava.net/Titan/comments/28844.html</wfw:comment><comments>http://www.blogjava.net/Titan/articles/28844.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Titan/comments/commentRss/28844.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Titan/services/trackbacks/28844.html</trackback:ping><description><![CDATA[<CENTER>
<P>原著：Steve Mansour <BR>sman@scruznet.com <BR><FONT size=-1>Revised: June 5, 1999<BR>(copied by jm /at/ jmason.org from http://www.scruz.net/%7esman/regexp.htm, after the original disappeared! ) </FONT></P>
<P>翻译：Neo Lee<BR>neo.lee@gmail.com<BR><FONT size=-1>2004年10月16日</FONT></P></CENTER>
<HR>

<P><A href="http://sitescooper.org/tao_regexps.html">英文版原文</A></P>
<P>译者按：原文因为年代久远，文中很多链接早已过期（主要是关于vi、sed等工具的介绍和手册），本译文中已将此类链接删除，如需检查这些链接可以查看上面链接的原文。除此之外基本照原文直译，括号中有“译者按”的部分是译者补充的说明。如有内容方面的问题请直接和Steve Mansor联系，当然，如果你只写中文，也可以和我联系。</P>
<HR>

<H1>目 录</H1>
<P><B><A href="http://net.pku.edu.cn/~yhf/tao_regexps_zh.html#WhatAreRegularExpressions">什么是正则表达式</A></B> <BR><B><A href="http://net.pku.edu.cn/~yhf/tao_regexps_zh.html#SimpleCommands">范例</A></B> <BR>&nbsp;&nbsp; <A href="http://net.pku.edu.cn/~yhf/tao_regexps_zh.html#SimpleCommands">简单</A> <BR>&nbsp;&nbsp; <A href="http://net.pku.edu.cn/~yhf/tao_regexps_zh.html#MediumDifficultyExamples">中级（神奇的咒语）</A> <BR>&nbsp;&nbsp; <A href="http://net.pku.edu.cn/~yhf/tao_regexps_zh.html#HardExamples">困难（不可思议的象形文字）</A><BR><B><A href="http://net.pku.edu.cn/~yhf/tao_regexps_zh.html#Regular_Expressions_In_Various_Tools">不同工具中的正则表达式</A></B> </P>
<P></P>
<HR width="100%">

<H1><A name=WhatAreRegularExpressions></A>什么是正则表达式</H1>一个正则表达式，就是用某种模式去匹配一类字符串的一个公式。很多人因为它们看上去比较古怪而且复杂所以不敢去使用——很不幸，这篇文章也不能够改变这一点，不过，经过一点点练习之后我就开始觉得这些复杂的表达式其实写起来还是相当简单的，而且，一旦你弄懂它们，你就能把数小时辛苦而且易错的文本处理工作压缩在几分钟（甚至几秒钟）内完成。正则表达式被各种文本编辑软件、类库（例如Rogue Wave的tools.h++）、脚本工具（像awk/grep/sed）广泛的支持，而且像Microsoft的Visual C++这种交互式IDE也开始支持它了。 
<P>我们将在如下的章节中利用一些例子来解释正则表达式的用法，绝大部分的例子是基于<B><TT>vi</TT></B>中的文本替换命令和<B><TT>grep</TT></B>文件搜索命令来书写的，不过它们都是比较典型的例子，其中的概念可以在sed、awk、perl和其他支持正则表达式的编程语言中使用。你可以看看<A href="http://net.pku.edu.cn/~yhf/tao_regexps_zh.html#Regular_Expressions_In_Various_Tools">不同工具中的正则表达式</A>这一节，其中有一些在别的工具中使用正则表达式的例子。还有一个关于vi中文本替换命令（s）的<A href="http://net.pku.edu.cn/~yhf/tao_regexps_zh.html#ViSubstitutionCommandSyntax">简单说明</A>附在文后供参考。</P>
<H2>正则表达式基础</H2>正则表达式由一些普通字符和一些<I>元字符（metacharacters）</I>组成。普通字符包括大小写的字母和数字，而元字符则具有特殊的含义，我们下面会给予解释。 
<P>在最简单的情况下，一个正则表达式看上去就是一个普通的查找串。例如，正则表达式"testing"中没有包含任何元字符，，它可以匹配"testing"和"123testing"等字符串，但是不能匹配"Testing"。</P>
<P>要想真正的用好正则表达式，正确的理解元字符是最重要的事情。下表列出了所有的元字符和对它们的一个简短的描述。 
<P>
<TABLE cellSpacing=2 cellPadding=2>
<TBODY>
<TR vAlign=baseline>
<TH align=left><B><I>元字符</I></B></TH>
<TD>&nbsp;</TD>
<TH align=left><B><I>描述</I></B></TH></TR>
<TR>
<TD>
<HR width="100%">
</TD>
<TD></TD>
<TD>
<HR width="100%">
</TD></TR>
<TR>
<TD vAlign=top align=middle>
<CENTER><B><TT><FONT face="Courier New"><FONT size=+1>.</FONT></FONT></TT></B> </CENTER></TD>
<TD></TD>
<TD>匹配任何单个字符。例如正则表达式<B><TT>r.t</TT></B>匹配这些字符串：<I>rat</I>、<I>rut</I>、<I>r t</I>，但是不匹配<I>root</I>。&nbsp;</TD></TR>
<TR>
<TD vAlign=top>
<CENTER><B><TT><FONT face="Courier New"><FONT size=+1>$</FONT></FONT></TT></B> </CENTER></TD>
<TD></TD>
<TD>匹配行结束符。例如正则表达式<B><TT>weasel$</TT></B> 能够匹配字符串"<I>He's a weasel</I>"的末尾，但是不能匹配字符串"<I>They are a bunch of weasels.</I>"。&nbsp;</TD></TR>
<TR>
<TD vAlign=top>
<CENTER><B><FONT size=+1>^</FONT></B> </CENTER></TD>
<TD></TD>
<TD>匹配一行的开始。例如正则表达式<B><TT>^When in</TT></B>能够匹配字符串"<I>When in the course of human events</I>"的开始，但是不能匹配"<I>What and When in the"。</I></TD></TR>
<TR>
<TD vAlign=top>
<CENTER><B><TT><FONT face="Courier New"><FONT size=+1>*</FONT></FONT></TT></B> </CENTER></TD>
<TD></TD>
<TD>匹配0或多个正好在它之前的那个字符。例如正则表达式<B><TT></TT></B><B><TT>.*</TT></B>意味着能够匹配任意数量的任何字符。</TD></TR>
<TR>
<TD vAlign=top>
<CENTER><B><TT><FONT face="Courier New"><FONT size=+1>\</FONT></FONT></TT></B> </CENTER></TD>
<TD></TD>
<TD>这是引用府，用来将这里列出的这些元字符当作普通的字符来进行匹配。例如正则表达式<B><TT>\$</TT></B>被用来匹配美元符号，而不是行尾，类似的，正则表达式<TT><STRONG>\.</STRONG></TT>用来匹配点字符，而不是任何字符的通配符。</TD></TR>
<TR>
<TD vAlign=top>
<CENTER><B><TT><FONT face="Courier New"><FONT size=+1>[ ]&nbsp;</FONT></FONT></TT></B> <BR><B><TT><FONT face="Courier New"><FONT size=+1>[c</FONT><FONT size=-1>1</FONT><FONT size=+1>-c</FONT><FONT size=-1>2</FONT><FONT size=+1>]</FONT></FONT></TT></B> <BR><B><TT><FONT face="Courier New"><FONT size=+1>[^c</FONT><FONT size=-1>1</FONT><FONT size=+1>-c</FONT><FONT size=-1>2</FONT><FONT size=+1>]</FONT></FONT></TT></B> </CENTER></TD>
<TD></TD>
<TD>匹配括号中的任何一个字符。例如正则表达式<B><TT>r[aou]t</TT></B>匹配<I>rat</I>、<I>rot</I>和<I>rut</I>，但是不匹配<I>ret</I>。可以在括号中使用连字符-来指定字符的区间，例如正则表达式<B><TT>[0-9]</TT></B>可以匹配任何数字字符；还可以制定多个区间，例如正则表达式<B><TT>[A-Za-z]</TT></B>可以匹配任何大小写字母。另一个重要的用法是“排除”，要想匹配<I>除了</I>指定区间之外的字符——也就是所谓的补集——在左边的括号和第一个字符之间使用^字符，例如正则表达式<B><TT>[^269A-Z]</TT></B> 将匹配除了2、6、9和所有大写字母之外的任何字符。</TD></TR>
<TR>
<TD vAlign=top>
<CENTER><B><TT><FONT face="Courier New"><FONT size=+1>\&lt; \&gt;</FONT></FONT></TT></B> </CENTER></TD>
<TD></TD>
<TD>匹配词（<EM>word</EM>）的开始（\&lt;）和结束（\&gt;）。例如正则表达式<B><TT><FONT face="Courier New">\&lt;the</FONT></TT></B>能够匹配字符串"<I>for the wise</I>"中的"the"，但是不能匹配字符串"<I>otherwise</I>"中的"the"。<STRONG>注意</STRONG>：这个元字符不是所有的软件都支持的。</TD></TR>
<TR>
<TD vAlign=top>
<CENTER><B><TT><FONT face="Courier New"><FONT size=+1>\( \)</FONT></FONT></TT></B> </CENTER></TD>
<TD></TD>
<TD>将 \( 和 \) 之间的表达式定义为“组”（<EM>group</EM>），并且将匹配这个表达式的字符保存到一个临时区域（一个正则表达式中最多可以保存9个），它们可以用 <B><TT>\1</TT></B> 到<B><TT>\9</TT></B> 的符号来引用。</TD></TR>
<TR>
<TD vAlign=baseline>
<CENTER><B><TT><FONT face="Courier New"><FONT size=+1>|</FONT></FONT></TT></B> </CENTER></TD>
<TD></TD>
<TD>将两个匹配条件进行逻辑“或”（<EM>Or</EM>）运算。例如正则表达式<B><TT><FONT face="Courier New">(him|her)</FONT></TT></B> 匹配"<I>it belongs to him</I>"和"<I>it belongs to her</I>"，但是不能匹配"<I>it belongs to them.</I>"。<STRONG>注意</STRONG>：这个元字符不是所有的软件都支持的。</TD></TR>
<TR vAlign=baseline>
<TD>
<CENTER><B><TT><FONT face="Courier New"><FONT size=+1>+</FONT></FONT></TT></B> </CENTER></TD>
<TD></TD>
<TD>匹配1或多个正好在它之前的那个字符。例如正则表达式<B><TT></TT></B><B><TT></TT></B><B><TT>9+</TT></B>匹配9、99、999等。<STRONG>注意</STRONG>：这个元字符不是所有的软件都支持的。</TD></TR>
<TR vAlign=baseline>
<TD>
<CENTER><B><TT><FONT size=+1>?</FONT></TT></B> </CENTER></TD>
<TD></TD>
<TD>匹配0或1个正好在它之前的那个字符。<STRONG>注意</STRONG>：这个元字符不是所有的软件都支持的。</TD></TR>
<TR vAlign=baseline>
<TD>
<CENTER><B><FONT size=+1><TT><FONT face="Courier New">\{</FONT></TT><I>i</I><TT><FONT face="Courier New">\}</FONT></TT></FONT></B> <BR><B><FONT size=+1><TT><FONT face="Courier New">\{</FONT></TT><I>i</I><TT><FONT face="Courier New">,</FONT></TT><I>j</I><TT><FONT face="Courier New">\}</FONT></TT></FONT></B> </CENTER></TD>
<TD></TD>
<TD vAlign=baseline>匹配指定数目的字符，这些字符是在它之前的表达式定义的。例如正则表达式<B><TT><FONT face="Courier New">A[0-9]\{3\}</FONT></TT></B> 能够匹配字符"A"后面跟着正好3个数字字符的串，例如A123、A348等，但是不匹配A1234。而正则表达式<B><TT><FONT face="Courier New">[0-9]\{4,6\}</FONT></TT></B> 匹配连续的任意4个、5个或者6个数字字符。<STRONG>注意</STRONG>：这个元字符不是所有的软件都支持的。</TD></TR></TBODY></TABLE></P>
<P></P>
<HR width="100%">

<P>最简单的元字符是点，它能够匹配任何单个字符（注意<STRONG>不</STRONG>包括新行符）。假定有个文件test.txt包含以下几行内容：</P>
<UL><TT>he is a rat</TT><BR><TT>he is in a rut</TT><BR><TT>the food is Rotten</TT><BR><TT>I like root beer</TT> </UL>我们可以使用grep命令来测试我们的正则表达式，grep命令使用正则表达式去尝试匹配指定文件的每一行，并将至少有一处匹配表达式的所有行显示出来。命令 
<UL><TT>grep r.t test.txt</TT> </UL>在test.txt文件中的每一行中搜索正则表达式<B><TT>r.t</TT></B>，并打印输出匹配的行。正则表达式<B><TT>r.t</TT></B>匹配一个<B><TT>r</TT></B>接着任何一个字符再接着一个<B><TT>t</TT></B>。所以它将匹配文件中的<B><TT>rat</TT></B>和<B><TT>rut</TT></B>，而不能匹配<B><TT>Rotten</TT></B>中的<B><TT>Rot</TT></B>，因为正则表达式是大小写敏感的。要想同时匹配大写和小写字母，应该使用字符区间元字符（方括号）。正则表达式<B><TT>[Rr]</TT></B>能够同时匹配<B><TT>R</TT></B>和<B><TT>r</TT></B>。所以，要想匹配一个大写或者小写的<B><TT>r</TT></B>接着任何一个字符再接着一个<B><TT>t</TT></B>就要使用这个表达式：<B><TT>[Rr].t</TT></B>。 
<P>要想匹配行首的字符要使用抑扬字符（<EM>^</EM>）——又是也被叫做插入符。例如，想找到text.txt中行首"he"打头的行，你可能会先用简单表达式<B><TT>he</TT></B>，但是这会匹配第三行的<B><TT>the</TT></B>，所以要使用正则表达式<B><TT>^he</TT></B>，它只匹配在行首出现的<B><TT>h</TT></B>。 </P>
<P>有时候指定“除了×××都匹配”会比较容易达到目的，当抑扬字符（<EM>^</EM>）出现在方括号中是，它表示“排除”，例如要匹配<B><TT>he</TT></B> ，但是排除前面是<B><TT>t</TT></B> or <B><TT>s</TT></B>的情性（也就是<B><TT>the</TT></B>和<B><TT>s</TT></B><B><TT>he</TT></B>），可以使用：<B><TT>[^st]he</TT></B>。 </P>
<P>可以使用方括号来指定多个字符区间。例如正则表达式<B><TT>[A-Za-z]</TT></B>匹配任何字母，包括大写和小写的；正则表达式<B><TT>[A-Za-z][A-Za-z]*</TT></B> 匹配一个字母后面接着0或者多个字母（大写或者小写）。当然我们也可以用元字符<B><TT>+</TT></B>做到同样的事情，也就是：<B><TT>[A-Za-z]+</TT></B> ，和<B><TT>[A-Za-z][A-Za-z]*</TT></B>完全等价。但是要注意元字符<B><TT>+</TT></B> 并不是所有支持正则表达式的程序都支持的。关于这一点可以参考后面的<A href="http://net.pku.edu.cn/~yhf/tao_regexps_zh.html#Regular%20Expressions%20Syntax">正则表达式语法支持情况</A>。</P>
<P>要指定特定数量的匹配，要使用大括号（注意必须使用反斜杠来转义）。想匹配所有<B><TT>100</TT></B>和<B><TT>1000</TT></B>的实例而排除<B><TT>10</TT></B>和<B><TT>10000</TT></B>，可以使用：<B><TT>10\{2,3\}</TT></B>，这个正则表达式匹配数字1后面跟着2或者3个0的模式。在这个元字符的使用中一个有用的变化是忽略第二个数字，例如正则表达式<B><TT>0\{3,\}</TT></B> 将匹配至少3个连续的0。</P>
<H2><A name=SimpleCommands></A>简单的例子</H2>
<P>这里有一些有代表性的、比较简单的例子。 
<P>
<TABLE cellSpacing=2 cellPadding=2>
<TBODY>
<TR>
<TD><B><I>vi 命令</I></B></TD>
<TD><B><I>作用</I></B></TD></TR>
<TR>
<TD>
<HR width="100%">
</TD>
<TD>
<HR width="100%">
</TD></TR>
<TR>
<TD><B><TT><FONT face="Courier New"><FONT size=+1>:%s/ */ /g</FONT></FONT></TT></B></TD>
<TD>把一个或者多个空格替换为一个空格。</TD></TR>
<TR>
<TD><B><TT><FONT face="Courier New"><FONT size=+1>:%s/ *$//</FONT></FONT></TT></B></TD>
<TD>去掉行尾的所有空格。</TD></TR>
<TR>
<TD><B><TT><FONT face="Courier New"><FONT size=+1>:%s/^/ /</FONT></FONT></TT></B></TD>
<TD>在每一行头上加入一个空格。</TD></TR>
<TR>
<TD><B><TT><FONT face="Courier New"><FONT size=+1>:%s/^[0-9][0-9]* //</FONT></FONT></TT></B></TD>
<TD>去掉行首的所有数字字符。</TD></TR>
<TR>
<TD><B><TT><FONT face="Courier New"><FONT size=+1>:%s/b[aeio]g/bug/g</FONT></FONT></TT></B></TD>
<TD>将所有的<I>bag</I>、<I>beg</I>、<I>big</I>和<I>bog</I>改为<I>bug</I>。&nbsp;</TD></TR>
<TR>
<TD><B><TT><FONT face="Courier New"><FONT size=+1>:%s/t\([aou]\)g/h\1t/g</FONT></FONT></TT></B></TD>
<TD>将所有<I>tag</I>、<I>tog</I>和<I>tug</I>分别改为<I>hat</I>、<I>hot</I>和<I>hug</I>（注意用group的用法和使用\1引用前面被匹配的字符）。</TD></TR>
<TR>
<TD></TD>
<TD></TD></TR></TBODY></TABLE>
<H2><A name=MediumDifficultyExamples></A>中级的例子（神奇的咒语）</H2>
<H3>例1</H3>
<P>将所有方法foo(<I>a,b,c</I>)的实例改为foo(<I>b,a,c</I>)。这里a、b和c可以是任何提供给方法foo()的参数。也就是说我们要实现这样的转换： 
<P>
<TABLE cellSpacing=4 cellPadding=0>
<TBODY>
<TR>
<TD><B>之前</B></TD>
<TD>&nbsp;</TD>
<TD><B>之后</B></TD></TR>
<TR>
<TD><TT>foo(10,7,2)</TT></TD>
<TD></TD>
<TD><TT>foo(7,10,2)</TT></TD></TR>
<TR>
<TD><TT>foo(x+13,y-2,10)</TT></TD>
<TD></TD>
<TD><TT>foo(y-2,x+13,10)</TT></TD></TR>
<TR>
<TD><TT>foo( bar(8), x+y+z, 5)</TT></TD>
<TD></TD>
<TD><TT>foo( x+y+z, bar(8), 5)</TT></TD></TR></TBODY></TABLE>
<P>下面这条替换命令能够实现这一魔法：</P>
<UL><B><TT><FONT face="Courier New">:%s/foo(\([^,]*\),\([^,]*\),\([^)]*\))/foo(\2,\1,\3)/g</FONT></TT></B> </UL>
<P>现在让我们把它打散来加以分析。写出这个表达式的基本思路是找出foo()和它的括号中的三个参数的位置。第一个参数是用这个表达式来识别的：：<B><TT><FONT face="Courier New">\([^,]*\)</FONT></TT></B>，我们可以从里向外来分析它：&nbsp; 
<P>
<TABLE>
<TBODY>
<TR>
<TD><B><TT><FONT face="Courier New">[^,]</FONT></TT></B></TD>
<TD>&nbsp;</TD>
<TD>除了逗号之外的任何字符</TD></TR>
<TR>
<TD><B><TT><FONT face="Courier New">[^,]*</FONT></TT></B></TD>
<TD></TD>
<TD>0或者多个非逗号字符</TD></TR>
<TR>
<TD><B><TT><FONT face="Courier New">\([^,]*\)</FONT></TT></B></TD>
<TD></TD>
<TD>将这些非逗号字符标记为<B><TT>\1</TT></B>，这样可以在之后的替换模式表达式中引用它</TD></TR>
<TR vAlign=baseline>
<TD><B><TT><FONT face="Courier New">\([^,]*\),</FONT></TT></B></TD>
<TD></TD>
<TD>我们必须找到0或者多个非逗号字符后面跟着一个逗号，并且非逗号字符那部分要标记出来以备后用。</TD></TR></TBODY></TABLE>
<P>现在正是指出一个使用正则表达式常见错误的最佳时机。为什么我们要使用<B><TT><FONT face="Courier New">[^,]*</FONT></TT></B>这样的一个表达式，而不是更加简单直接的写法，例如：<B><TT><FONT face="Courier New">.*</FONT></TT></B>，来匹配第一个参数呢？设想我们使用模式<B><TT><FONT face="Courier New">.*</FONT></TT></B>来匹配字符串"10,7,2"，它应该匹配"10,"还是"10,7,"？为了解决这个两义性（ambiguity），正则表达式规定一律按照最长的串来，在上面的例子中就是"10,7,"，显然这样就找出了两个参数而不是我们期望的一个。所以，我们要使用<B><TT><FONT face="Courier New">[^,]*</FONT></TT></B>来强制取出第一个逗号之前的部分。</P>
<P>这个表达式我们已经分析到了：<B><TT><FONT face="Courier New">foo(\([^,]*\)</FONT></TT></B>，这一段可以简单的翻译为“当你找到<B><TT>foo(</TT></B>就把其后直到第一个逗号之前的部分标记为<B><TT><FONT face="Courier New">\1</FONT></TT></B>”。然后我们使用同样的办法标记第二个参数为<B><TT><FONT face="Courier New">\2</FONT></TT></B>。对第三个参数的标记方法也是一样，只是我们要搜索所有的字符直到右括号。我们并没有必要去搜索第三个参数，因为我们不需要调整它的位置，但是这样的模式能够保证我们只去替换那些有三个参数的foo()方法调用，在foo()是一个重载（overoading）方法时这种明确的模式往往是比较保险的。然后，在替换部分，我们找到foo()的对应实例，然后利用标记好的部分进行替换，是的第一和第二个参数交换位置。</P>
<H3>例2</H3>假设有一个CSV（comma separated value）文件，里面有一些我们需要的信息，但是格式却有问题，目前数据的列顺序是：姓名，公司名，州名缩写，邮政编码，现在我们希望讲这些数据重新组织，以便在我们的某个软件中使用，需要的格式为：姓名，州名缩写-邮政编码，公司名。也就是说，我们要调整列顺序，还要合并两个列来构成一个新列。另外，我们的软件不能接受逗号前后面有任何空格（包括空格和制表符）所以我们还必须要去掉逗号前后的所有空格。 
<P>这里有几行我们现在的数据：</P>
<UL><TT>Bill Jones,&nbsp;&nbsp;&nbsp;&nbsp; HI-TEK Corporation ,&nbsp; CA, 95011</TT> <BR><TT><FONT face="Courier New">Sharon Lee Smith,&nbsp; Design Works Incorporated,&nbsp; CA, 95012</FONT></TT> <BR><TT><FONT face="Courier New">B. Amos&nbsp;&nbsp; ,&nbsp; Hill Street Cafe,&nbsp; CA, 95013</FONT></TT> <BR><TT><FONT face="Courier New">Alexander Weatherworth,&nbsp; The Crafts Store,&nbsp; CA, 95014</FONT></TT> <BR><TT><FONT face="Courier New">...</FONT></TT> </UL>我们希望把它变成这个样子： 
<UL><TT>Bill Jones,CA 95011,HI-TEK Corporation</TT> <BR><TT><FONT face="Courier New">Sharon Lee Smith,CA 95012,Design Works Incorporated</FONT></TT> <BR><TT><FONT face="Courier New">B. Amos,CA 95013,Hill Street Cafe</FONT></TT> <BR><TT><FONT face="Courier New">Alexander Weatherworth,CA 95014,The Crafts Store</FONT></TT> <BR><TT><FONT face="Courier New">...</FONT></TT> </UL>我们将用两个正则表达式来解决这个问题。第一个移动列和合并列，第二个用来去掉空格。 
<P>下面就是第一个替换命令：</P>
<UL><B><TT><FONT face="Courier New">:%s/\([^,]*\),\([^,]*\),\([^,]*\),\(.*\)/\1,\3 \4,\2/</FONT></TT></B> </UL>这里的方法跟例1基本一样，第一个列（姓名）用这个表达式来匹配：<B><TT><FONT face="Courier New">\([^,]*\)</FONT></TT></B>，即第一个逗号之前的所有字符，而姓名内容被用<B><TT><FONT face="Courier New">\1</FONT></TT></B>标记下来。公司名和州名缩写字段用同样的方法标记为<B><TT><FONT face="Courier New">\2</FONT></TT></B>和<B><TT><FONT face="Courier New">\3</FONT></TT></B>，而最后一个字段用<B><TT><FONT face="Courier New">\(.*\)</FONT></TT></B>来匹配（"匹配所有字符直到行末"）。替换部分则引用上面标记的那些内容来进行构造。 
<P>下面这个替换命令则用来去除空格：</P>
<UL><B><TT><FONT face="Courier New">:%s/[ \t]*,[ \t]*/,/g</FONT></TT></B> </UL>我们还是分解来看：<B><TT><FONT face="Courier New">[ \t]</FONT></TT></B>匹配空格/制表符，<B><TT><FONT face="Courier New">[ \t]*</FONT></TT></B> 匹配0或多个空格/制表符，<B><TT>[ \t]*</TT></B>,匹配0或多个空格/制表符后面再加一个逗号，最后，<B><TT><FONT face="Courier New">[ \t]*,[ \t]*</FONT></TT></B>匹配0或多个空格/制表符接着一个逗号再接着0或多个空格/制表符。在替换部分，我们简单的我们找到的所有东西替换成一个逗号。这里我们使用了结尾的可选的<B><TT>g</TT></B>参数，这表示在每行中对所有匹配的串执行替换（而不是缺省的只替换第一个匹配串）。 
<H3>例3</H3>假设有一个多字符的片断重复出现，例如： 
<BLOCKQUOTE><TT>Billy tried really hard</TT> <BR><TT>Sally tried really really hard</TT> <BR><TT>Timmy tried really really really hard</TT> <BR><TT>Johnny tried really really really really hard</TT></BLOCKQUOTE>而你想把"really"、"really really"，以及任意数量连续出现的"really"字符串换成一个简单的"very"（simple is good!），那么以下命令： 
<BLOCKQUOTE><B><TT>:%s/\(really \)\(really \)*/very /</TT></B></BLOCKQUOTE>就会把上述的文本变成： 
<BLOCKQUOTE><TT>Billy tried very hard</TT> <BR><TT>Sally tried very hard</TT> <BR><TT>Timmy tried very hard</TT> <BR><TT>Johnny tried very hard</TT></BLOCKQUOTE>表达式<B><TT>\(really \)*</TT></B>匹配0或多个连续的"really "（注意结尾有个空格），而<B><TT>\(really \)\(really \)*</TT></B> 匹配1个或多个连续的"really "实例。 
<H2><A name=HardExamples></A>困难的例子（不可思议的象形文字）</H2><I>Coming soon</I>. 
<P></P>
<HR>

<H1><A name=Regular_Expressions_In_Various_Tools></A>不同工具中的正则表达式</H1>OK，你已经准备使用RE（regular expressions，正则表达式），但是你并准备使用vi。所以，在这里我们给出一些在其他工具中使用RE的例子。另外，我还会总结一下你在不同程序之间使用RE可能发现的区别。 
<P>当然，你也可以在Visual C++编辑器中使用RE。选择Edit-&gt;Replace，然后选择"Regular expression"选择框，Find What输入框对应上面介绍的vi命令<B><TT>:%s/pat1/pat2/g</TT></B>中的pat1部分，而Replace输入框对应pat2部分。但是，为了得到vi的执行范围和<B><TT>g</TT></B>选项，你要使用Replace All或者适当的手工Find Next and Replace（译者按：知道为啥有人骂微软弱智了吧，虽然VC中可以选中一个范围的文本，然后在其中执行替换，但是总之不够vi那么灵活和典雅）。</P>
<H2>sed</H2>
<P>Sed是<B><U>S</U></B>tream <B><U>ED</U></B>itor的缩写，是Unix下常用的基于文件和管道的编辑工具，可以在手册中得到关于sed的详细信息。 </P>
<P>这里是一些有趣的sed脚本，假定我们正在处理一个叫做price.txt的文件。注意这些编辑并不会改变源文件，sed只是处理源文件的每一行并把结果显示在标准输出中（当然很容易使用重定向来定制）： 
<P>
<TABLE>
<TBODY>
<TR>
<TD><B><I>sed脚本</I></B></TD>
<TD>&nbsp;</TD>
<TD><B><I>描述</I></B></TD></TR>
<TR>
<TD>
<HR width="100%">
</TD>
<TD></TD>
<TD>
<HR width="100%">
</TD></TR>
<TR vAlign=baseline>
<TD><B><TT>sed 's/^$/d' price.txt</TT></B></TD>
<TD></TD>
<TD>删除所有空行</TD></TR>
<TR>
<TD><B><TT>sed 's/^[ \t]*$/d' price.txt</TT></B></TD>
<TD></TD>
<TD>删除所有只包含空格或者制表符的行</TD></TR>
<TR>
<TD><B><TT>sed 's/"//g' price.txt</TT></B></TD>
<TD></TD>
<TD>删除所有引号</TD></TR></TBODY></TABLE></P>
<H2>awk</H2>awk是一种编程语言，可以用来对文本数据进行复杂的分析和处理。可以在手册中得到关于awk的详细信息。这个古怪的名字是它作者们的姓的缩写（Aho，Weinberger和Kernighan）。 
<P>在Aho，Weinberger和Kernighan的书<U>The AWK Programming Language</U>中有很多很好的awk的例子，请不要让下面这些微不足道的脚本例子限制你对awk强大能力的理解。我们同样假定我们针对price.txt文件进行处理，跟sed一样，awk也只是把结果显示在终端上。&nbsp; 
<P>
<TABLE>
<TBODY>
<TR>
<TD><B><I>awk脚本</I></B></TD>
<TD>&nbsp;</TD>
<TD><B><I>描述</I></B></TD></TR>
<TR>
<TD>
<HR width="100%">
</TD>
<TD></TD>
<TD>
<HR width="100%">
</TD></TR>
<TR vAlign=baseline>
<TD><B><TT>awk '$0 !~ /^$/' price.txt</TT></B></TD>
<TD></TD>
<TD>删除所有空行</TD></TR>
<TR>
<TD><B><TT>awk 'NF &gt; 0' price.txt</TT></B></TD>
<TD></TD>
<TD>awk中一个更好的删除所有行的办法</TD></TR>
<TR vAlign=baseline>
<TD><B><TT>awk '$2 ~ /^[JT]/ {print $3}' price.txt</TT></B></TD>
<TD></TD>
<TD>打印所有第二个字段是'J'或者'T'打头的行中的第三个字段</TD></TR>
<TR vAlign=baseline>
<TD noWrap><B><TT>awk '$2 !~ /[Mm]isc/ {print $3 + $4}' price.txt</TT></B></TD>
<TD></TD>
<TD>针对所有第二个字段不包含'Misc'或者'misc'的行，打印第3和第4列的和（假定为数字）</TD></TR>
<TR vAlign=baseline>
<TD><B><TT>awk '$3 !~ /^[0-9]+\.[0-9]*$/ {print $0}' price.txt</TT></B></TD>
<TD></TD>
<TD>打印所有第三个字段不是数字的行，这里数字是指<TT>d.d</TT>或者<TT>d这样的形式，其中</TT><TT>d</TT>是0到9的任何数字</TD></TR>
<TR vAlign=baseline>
<TD><B><TT>awk '$2 ~ /John|Fred/ {print $0}' price.txt</TT></B></TD>
<TD></TD>
<TD>如果第二个字段包含'John'或者'Fred'则打印整行</TD></TR></TBODY></TABLE></P>
<H2>grep</H2>grep是一个用来在一个或者多个文件或者输入流中使用RE进行查找的程序。它的name编程语言可以用来针对文件和管道进行处理。可以在手册中得到关于grep的完整信息。这个同样古怪的名字来源于vi的一个命令，<B><TT>g/</TT></B><I>re</I><B><TT>/p</TT></B>，意思是<B>g</B>lobal <B>r</B>egular <B>e</B>xpression <B>p</B>rint。 
<P>下面的例子中我们假定在文件phone.txt中包含以下的文本，——其格式是姓加一个逗号，然后是名，然后是一个制表符，然后是电话号码：</P>
<UL>
<P><TT>Francis, John&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5-3871</TT> <BR><TT>Wong, Fred&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4-4123</TT> <BR><TT>Jones, Thomas&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1-4122</TT> <BR><TT>Salazar, Richard&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5-2522</TT></P></UL>
<P>
<TABLE>
<TBODY>
<TR>
<TD><B><I>grep命令</I></B></TD>
<TD><B><I>&nbsp;</I></B></TD>
<TD><B><I>描述</I></B></TD></TR>
<TR>
<TD>
<HR width="100%">
</TD>
<TD></TD>
<TD>
<HR width="100%">
</TD></TR>
<TR vAlign=baseline>
<TD><B><TT>grep '\t5-...1' phone.txt</TT></B></TD>
<TD></TD>
<TD>把所有电话号码以5开头以1结束的行打印出来，注意制表符是用<B><TT>\t</TT></B>表示的</TD></TR>
<TR vAlign=baseline>
<TD noWrap><B><TT>grep '^S[^ ]* R' phone.txt</TT></B></TD>
<TD></TD>
<TD>打印所有姓以S打头和名以R打头的行</TD></TR>
<TR vAlign=baseline>
<TD><B><TT>grep '^[JW]' phone.txt</TT></B></TD>
<TD></TD>
<TD>打印所有姓开头是J或者W的行</TD></TR>
<TR vAlign=baseline>
<TD><B><TT>grep ', ....\t' phone.txt</TT></B></TD>
<TD></TD>
<TD>打印所有姓是4个字符的行，注意制表符是用<B><TT>\t</TT></B>表示的</TD></TR>
<TR vAlign=baseline>
<TD><B><TT>grep -v '^[JW]' phone.txt</TT></B></TD>
<TD></TD>
<TD>打印所有不以J或者W开头的行</TD></TR>
<TR vAlign=baseline>
<TD><B><TT>grep '^[M-Z]' phone.txt</TT></B></TD>
<TD></TD>
<TD>打印所有姓的开头是M到Z之间任一字符的行</TD></TR>
<TR vAlign=baseline>
<TD><B><TT>grep '^[M-Z].*[12]' phone.txt</TT></B></TD>
<TD></TD>
<TD>打印所有姓的开头是M到Z之间任一字符，并且点号号码结尾是1或者2的行</TD></TR></TBODY></TABLE>
<H2>egrep</H2>egrep是grep的一个扩展版本，它在它的正则表达式中支持更多的元字符。下面的例子中我们假定在文件phone.txt中包含以下的文本，——其格式是姓加一个逗号，然后是名，然后是一个制表符，然后是电话号码： 
<UL><TT>Francis, John&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5-3871</TT> <BR><TT>Wong, Fred&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4-4123</TT> <BR><TT>Jones, Thomas&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1-4122</TT> <BR><TT>Salazar, Richard&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5-2522</TT> </UL>
<P>
<TABLE>
<TBODY>
<TR>
<TD><B><I>egrep command</I></B></TD>
<TD><B><I>&nbsp;</I></B></TD>
<TD><B><I>Description</I></B></TD></TR>
<TR>
<TD>
<HR width="100%">
</TD>
<TD></TD>
<TD>
<HR width="100%">
</TD></TR>
<TR vAlign=baseline>
<TD><B><TT>egrep '(John|Fred)' phone.txt</TT></B></TD>
<TD></TD>
<TD>打印所有包含名字<I>John</I>或者<I>Fred</I>的行</TD></TR>
<TR vAlign=baseline>
<TD noWrap><B><TT>egrep 'John|22$|^W' phone.txt</TT></B></TD>
<TD></TD>
<TD>打印所有包含<I>John</I> 或者以22结束或者以<I>W</I>的行</TD></TR>
<TR>
<TD><B><TT>egrep 'net(work)?s' report.txt</TT></B></TD>
<TD></TD>
<TD>从report.txt中找到所有包含<I>networks</I>或者<I>nets</I>的行</TD></TR></TBODY></TABLE>
<H2>
<HR width="100%">
</H2>
<H1><A name="Regular Expressions Syntax"></A>正则表达式语法支持情况</H1>
<TABLE cellSpacing=0 border=1>
<TBODY>
<TR>
<TD><B>命令或环境</B></TD>
<TD><B><TT><FONT face="Courier New">.</FONT></TT></B></TD>
<TD><B><TT><FONT face="Courier New">[ ]</FONT></TT></B></TD>
<TD><B><TT><FONT face="Courier New">^</FONT></TT></B></TD>
<TD><B><TT><FONT face="Courier New">$</FONT></TT></B></TD>
<TD><B><TT><FONT face="Courier New">\( \)</FONT></TT></B></TD>
<TD><B><TT><FONT face="Courier New">\{ \}</FONT></TT></B></TD>
<TD><B><TT><FONT face="Courier New">?</FONT></TT></B></TD>
<TD><B><TT><FONT face="Courier New">+</FONT></TT></B></TD>
<TD><B><TT><FONT face="Courier New">|</FONT></TT></B></TD>
<TD><B><TT><FONT face="Courier New">( )</FONT></TT></B></TD></TR>
<TR>
<TD>vi</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD></TR>
<TR>
<TD>Visual C++</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD></TR>
<TR>
<TD>awk</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD></TR>
<TR>
<TD>sed</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD></TR>
<TR>
<TD>Tcl</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD></TR>
<TR>
<TD>ex</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD></TR>
<TR>
<TD>grep</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD></TR>
<TR>
<TD>egrep</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD></TR>
<TR>
<TD>fgrep</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;X&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD></TR>
<TR>
<TD>perl</TD>
<TD>&nbsp;X</TD>
<TD>&nbsp;X</TD>
<TD>&nbsp;X</TD>
<TD>&nbsp;X</TD>
<TD>&nbsp;X</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;X</TD>
<TD>&nbsp;X</TD>
<TD>&nbsp;X</TD>
<TD>&nbsp;X</TD></TR></TBODY></TABLE>
<P>&nbsp;</P>
<HR>

<H1><A name=ViSubstitutionCommandSyntax></A>vi替换命令简介</H1>Vi的替换命令： 
<UL><B><TT>:</TT></B><I>range</I><B><TT>s/</TT></B><I>pat1</I><B><TT>/</TT></B><I>pat2</I><B><TT>/g</TT></B> </UL>其中 
<UL><B><TT>:</TT></B> 这是Vi的命令执行界面。 </UL>
<UL><I>range </I>是命令执行范围的指定，可以使用百分号（%）表示所有行，使用点（.）表示当前行，使用美元符号（$）表示最后一行。你还可以使用行号，例如<B><TT>10,20</TT></B>表示第10到20行，<B><TT>.,$</TT></B>表示当前行到最后一行，<B><TT>.+2,$-5</TT></B>表示当前行后两行直到全文的倒数第五行，等等。 
<P><B><TT>s</TT></B> 表示其后是一个替换命令。</P>
<P><I>pat1 </I>这是要查找的一个正则表达式，这篇文章中有一大堆例子。</P></UL>
<UL><I>pat2 </I>这是希望把匹配串变成的模式的正则表达式，这篇文章中有一大堆例子。 
<P><B><TT>g</TT></B> 可选标志，带这个标志表示替换将针对行中每个匹配的串进行，否则则只替换行中第一个匹配串。</P></UL>网上有很多vi的在线手册，你可以访问他们以获得更加完整的信息。 <img src ="http://www.blogjava.net/Titan/aggbug/28844.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Titan/" target="_blank">Titan</a> 2006-01-20 23:58 <a href="http://www.blogjava.net/Titan/articles/28844.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>1M内存可用来缓存多少对象？ </title><link>http://www.blogjava.net/Titan/articles/28367.html</link><dc:creator>Titan</dc:creator><author>Titan</author><pubDate>Tue, 17 Jan 2006 13:18:00 GMT</pubDate><guid>http://www.blogjava.net/Titan/articles/28367.html</guid><wfw:comment>http://www.blogjava.net/Titan/comments/28367.html</wfw:comment><comments>http://www.blogjava.net/Titan/articles/28367.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Titan/comments/commentRss/28367.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Titan/services/trackbacks/28367.html</trackback:ping><description><![CDATA[为了提高系统的响应性能，一般都会采用缓存技术来实现，如果用象ehcache、oscache这样的开源的cache工具来实现，一般都需要由开发人员来设置maxElementsInMemory这个值，但这个值在设置的时候大家都是怎么去设置的呢？凭想像还是随便写一个值呢？这个值设的过大嘛有可能会造成outofmemory，设的过小嘛又浪费服务器巨大的内存，为了能够更好的设置这个值，我写了个测试程序来估算1M内存能够缓存多少个对象，代码如下：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #008080">&nbsp;1</SPAN><IMG id=Codehighlighter1_23_1365_Open_Image onclick="this.style.display='none'; Codehighlighter1_23_1365_Open_Text.style.display='none'; Codehighlighter1_23_1365_Closed_Image.style.display='inline'; Codehighlighter1_23_1365_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_23_1365_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_23_1365_Closed_Text.style.display='none'; Codehighlighter1_23_1365_Open_Image.style.display='inline'; Codehighlighter1_23_1365_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;testSpike()</SPAN><SPAN id=Codehighlighter1_23_1365_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_23_1365_Open_Text><SPAN style="COLOR: #000000">{<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;2</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">最大的内存为：</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">Runtime.getRuntime().maxMemory()</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;3</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">总的内存为：</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">Runtime.getRuntime().totalMemory()</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;4</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">==================================</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;5</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">&nbsp;currMemory</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">Runtime.getRuntime().freeMemory();<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;6</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">目前可用的内存为：</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">currMemory</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;7</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">==================================</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;8</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map&nbsp;cache</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;HashMap();<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;9</SPAN><SPAN style="COLOR: #000000"><IMG id=Codehighlighter1_437_884_Open_Image onclick="this.style.display='none'; Codehighlighter1_437_884_Open_Text.style.display='none'; Codehighlighter1_437_884_Closed_Image.style.display='inline'; Codehighlighter1_437_884_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_437_884_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_437_884_Closed_Text.style.display='none'; Codehighlighter1_437_884_Open_Image.style.display='inline'; Codehighlighter1_437_884_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">500000</SPAN><SPAN style="COLOR: #000000">;&nbsp;i</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN id=Codehighlighter1_437_884_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_437_884_Open_Text><SPAN style="COLOR: #000000">{<BR></SPAN><SPAN style="COLOR: #008080">10</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MockBean&nbsp;bean</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;MockBean();<BR></SPAN><SPAN style="COLOR: #008080">11</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bean.setId(i);<BR></SPAN><SPAN style="COLOR: #008080">12</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bean.setName(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">jerry</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">i);<BR></SPAN><SPAN style="COLOR: #008080">13</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bean.setValue(i</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">jerry</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">14</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cache.put(String.valueOf(i),&nbsp;bean);<BR></SPAN><SPAN style="COLOR: #008080">15</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">&nbsp;tempMemory</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">Runtime.getRuntime().freeMemory();<BR></SPAN><SPAN style="COLOR: #008080">16</SPAN><SPAN style="COLOR: #000000"><IMG id=Codehighlighter1_744_874_Open_Image onclick="this.style.display='none'; Codehighlighter1_744_874_Open_Text.style.display='none'; Codehighlighter1_744_874_Closed_Image.style.display='inline'; Codehighlighter1_744_874_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_744_874_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_744_874_Closed_Text.style.display='none'; Codehighlighter1_744_874_Open_Image.style.display='inline'; Codehighlighter1_744_874_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">((currMemory</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">tempMemory)</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN id=Codehighlighter1_744_874_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_744_874_Open_Text><SPAN style="COLOR: #000000">{<BR></SPAN><SPAN style="COLOR: #008080">17</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">此时可用的内存为：</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">tempMemory</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">18</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">此时缓存了：</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">i</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">个对象</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">19</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">break</SPAN><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #008080">20</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">21</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">22</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">==================================</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">23</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cache.clear();<BR></SPAN><SPAN style="COLOR: #008080">24</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">&nbsp;tempMemory</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">Runtime.getRuntime().freeMemory();<BR></SPAN><SPAN style="COLOR: #008080">25</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">目前可用的内存为：</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">tempMemory</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">26</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">消耗的内存为：</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">(currMemory</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">tempMemory)</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">27</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">==================================</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">28</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Runtime.getRuntime().gc();<BR></SPAN><SPAN style="COLOR: #008080">29</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempMemory</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">Runtime.getRuntime().freeMemory();<BR></SPAN><SPAN style="COLOR: #008080">30</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">目前可用的内存为：</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">tempMemory</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">31</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">消耗的内存为：</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">(currMemory</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">tempMemory)</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">32</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">33</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">34</SPAN><SPAN style="COLOR: #000000"><IMG id=Codehighlighter1_1406_1445_Open_Image onclick="this.style.display='none'; Codehighlighter1_1406_1445_Open_Text.style.display='none'; Codehighlighter1_1406_1445_Closed_Image.style.display='inline'; Codehighlighter1_1406_1445_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_1406_1445_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1406_1445_Closed_Text.style.display='none'; Codehighlighter1_1406_1445_Open_Image.style.display='inline'; Codehighlighter1_1406_1445_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;print(String&nbsp;msg)</SPAN><SPAN id=Codehighlighter1_1406_1445_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_1406_1445_Open_Text><SPAN style="COLOR: #000000">{<BR></SPAN><SPAN style="COLOR: #008080">35</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(msg);<BR></SPAN><SPAN style="COLOR: #008080">36</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN></DIV>在我机器上运行的结果是1M内存可缓存大概4479个对象，同时可以看到，在cache.clear后内存并没有变化，因为gc是没那么及时的，这个时候显式的调用gc则会发现可用的内存量甚至比最初都多，呵呵<BR>当然，这里只是个简单的测试，这里测试的也只是缓存一个非常简单的bean对象，缓存的对象消耗的内存大小还需要根据这个对象中具体的内容而定，比如当缓存的是blob类型的字段的时候，可想而知，这个时候消耗的内存量绝对是不同的。<BR>这里只是建议大家在对系统性能做优化时最好根据需要缓存的内容做一个估算，设置好应用所需要的jvm的内存值，以便充分利用服务器的硬件资源。 <img src ="http://www.blogjava.net/Titan/aggbug/28367.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Titan/" target="_blank">Titan</a> 2006-01-17 21:18 <a href="http://www.blogjava.net/Titan/articles/28367.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]一些好用的Eclipse 3.0插件 </title><link>http://www.blogjava.net/Titan/articles/28063.html</link><dc:creator>Titan</dc:creator><author>Titan</author><pubDate>Sat, 14 Jan 2006 16:09:00 GMT</pubDate><guid>http://www.blogjava.net/Titan/articles/28063.html</guid><wfw:comment>http://www.blogjava.net/Titan/comments/28063.html</wfw:comment><comments>http://www.blogjava.net/Titan/articles/28063.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Titan/comments/commentRss/28063.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Titan/services/trackbacks/28063.html</trackback:ping><description><![CDATA[<DIV>1.MyEclipse&nbsp; J2EE开发插件，支持SERVLET/JSP/EJB/数据库操纵等<BR><A href="http://www.myeclipseide.com/"><FONT color=#4a664d>http://www.myeclipseide.com/</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>2.Properties Editor&nbsp; 编辑java的属性文件，并可以自动存盘为Unicode格式<BR><A href="http://propedit.sourceforge.jp/index_en.html"><FONT color=#4a664d>http://propedit.sourceforge.jp/index_en.html</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>3.Colorer Take&nbsp; 为上百种类型的文件按语法着色<BR><A href="http://colorer.sourceforge.net/"><FONT color=#4a664d>http://colorer.sourceforge.net/</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>4.XMLBuddy 编辑xml文件<BR><A href="http://www.xmlbuddy.com/"><FONT color=#4a664d>http://www.xmlbuddy.com/</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>5.Code Folding&nbsp; 加入多种代码折叠功能（比eclipse自带的更多）<BR><A href="http://www.coffee-bytes.com/servlet/PlatformSupport"><FONT color=#4a664d>http://www.coffee-bytes.com/servlet/PlatformSupport</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>6.Easy Explorer&nbsp; 从eclipse中访问选定文件、目录所在的文件夹<BR><A href="http://easystruts.sourceforge.net/"><FONT color=#4a664d>http://easystruts.sourceforge.net/</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>7.Fat Jar 打包插件，可以方便的完成各种打包任务，可以包含外部的包等<BR><A href="http://fjep.sourceforge.net/"><FONT color=#4a664d>http://fjep.sourceforge.net/</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>8.RegEx Test 测试正则表达式<BR><A href="http://brosinski.com/stephan/archives/000028.php"><FONT color=#4a664d>http://brosinski.com/stephan/archives/000028.php</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>9.JasperAssistant 报表插件（强，要钱的）<BR><A href="http://www.jasperassistant.com/"><FONT color=#4a664d>http://www.jasperassistant.com/</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>10.Jigloo GUI Builder ＪＡＶＡ的ＧＵＩ编辑插件<BR><A href="http://cloudgarden.com/jigloo/"><FONT color=#4a664d>http://cloudgarden.com/jigloo/</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>11.Profiler 性能跟踪、测量工具，能跟踪、测量ＢＳ程序<BR><A href="http://sourceforge.net/projects/eclipsecolorer/"><FONT color=#4a664d>http://sourceforge.net/projects/eclipsecolorer/</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>12.AdvanQas 提供对if/else等条件语句的提示和快捷帮助（自动更改结构等）<BR><A href="http://eclipsecolorer.sourceforge.net/advanqas/index.html"><FONT color=#4a664d>http://eclipsecolorer.sourceforge.net/advanqas/index.html</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>13.Log4E&nbsp;&nbsp;&nbsp;&nbsp; Log4j插件，提供各种和Log4j相关的任务，如为方法、类添加一个logger等<BR><A href="http://log4e.jayefem.de/index.php/Main_Page"><FONT color=#4a664d>http://log4e.jayefem.de/index.php/Main_Page</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>14.VSSPlugin VSS插件<BR><A href="http://sourceforge.net/projects/vssplugin"><FONT color=#4a664d>http://sourceforge.net/projects/vssplugin</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>15.Implementors&nbsp;&nbsp; 提供跳转到一个方法的实现类，而不是接中的功能（实用!）<BR><A href="http://eclipse-tools.sourceforge.net/implementors/"><FONT color=#4a664d>http://eclipse-tools.sourceforge.net/implementors/</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>16.Call Hierarchy 显示一个方法的调用层次（被哪些方法调，调了哪些方法）<BR><A href="http://eclipse-tools.sourceforge.net/call-hierarchy/index.html"><FONT color=#4a664d>http://eclipse-tools.sourceforge.net/call-hierarchy/index.html</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>17.EclipseTidy 检查和格式化HTML/XML文件<BR><A href="http://eclipsetidy.sourceforge.net/"><FONT color=#4a664d>http://eclipsetidy.sourceforge.net/</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>18.Checkclipse 检查代码的风格、写法是否符合规范<BR><A href="http://www.mvmsoft.de/content/plugins/checkclipse/checkclipse.htm"><FONT color=#4a664d>http://www.mvmsoft.de/content/plugins/checkclipse/checkclipse.htm</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>19.Hibernate Synchronizer Hibernate插件，自动映射等<BR><A href="http://www.binamics.com/hibernatesync/"><FONT color=#4a664d>http://www.binamics.com/hibernatesync/</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>20.VeloEclipse&nbsp; Velocity插件<BR><A href="http://propsorter.sourceforge.net/"><FONT color=#4a664d>http://propsorter.sourceforge.net/</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>21.EditorList&nbsp;&nbsp; 方便的列出所有打开的Editor<BR><A href="http://editorlist.sourceforge.net/"><FONT color=#4a664d>http://editorlist.sourceforge.net/</FONT></A></DIV>
<DIV><FONT color=#4a664d></FONT>&nbsp;</DIV>
<DIV>22.MemoryManager 内存占用率的监视<BR><A href="http://cloudgarden.com/memorymanager/"><FONT color=#4a664d>http://cloudgarden.com/memorymanager/</FONT></A></DIV><img src ="http://www.blogjava.net/Titan/aggbug/28063.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Titan/" target="_blank">Titan</a> 2006-01-15 00:09 <a href="http://www.blogjava.net/Titan/articles/28063.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]JDBC连接数据库经验技巧集萃 </title><link>http://www.blogjava.net/Titan/articles/28060.html</link><dc:creator>Titan</dc:creator><author>Titan</author><pubDate>Sat, 14 Jan 2006 16:02:00 GMT</pubDate><guid>http://www.blogjava.net/Titan/articles/28060.html</guid><wfw:comment>http://www.blogjava.net/Titan/comments/28060.html</wfw:comment><comments>http://www.blogjava.net/Titan/articles/28060.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Titan/comments/commentRss/28060.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Titan/services/trackbacks/28060.html</trackback:ping><description><![CDATA[Java数据库连接（JDBC）由一组用 Java 编程语言编写的类和接口组成。JDBC 为工具/数据库开发人员提供了一个标准的 API，使他们能够用纯Java API 来编写数据库应用程序。然而各个开发商的接口并不完全相同，所以开发环境的变化会带来一定的配置变化。本文主要集合了不同数据库的连接方式。<BR><BR>　　<B>一、连接各种数据库方式速查表</B><BR><BR>　　下面罗列了各种数据库使用JDBC连接的方式，可以作为一个手册使用。 <BR><BR>　　1、Oracle8/8i/9i数据库（thin模式） <BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#dadacf border=1>
<TBODY>
<TR>
<TD>Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); <BR>String url="jdbc:oracle:thin:@localhost:1521:orcl"; //orcl为数据库的SID <BR>String user="test"; <BR>String password="test"; <BR>Connection conn= DriverManager.getConnection(url,user,password); </TD></TR></TBODY></TABLE><BR>　　2、DB2数据库 <BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#dadacf border=1>
<TBODY>
<TR>
<TD>Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance(); <BR>String url="jdbc:db2://localhost:5000/sample"; //sample为你的数据库名 <BR>String user="admin"; <BR>String password=""; <BR>Connection conn= DriverManager.getConnection(url,user,password); </TD></TR></TBODY></TABLE><BR>　　3、Sql Server7.0/2000数据库 <BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#dadacf border=1>
<TBODY>
<TR>
<TD>Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance(); <BR>String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb"; <BR>//mydb为数据库 <BR>String user="sa"; <BR>String password=""; <BR>Connection conn= DriverManager.getConnection(url,user,password); </TD></TR></TBODY></TABLE><BR>　　4、Sybase数据库 <BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#dadacf border=1>
<TBODY>
<TR>
<TD>Class.forName("com.sybase.jdbc.SybDriver").newInstance(); <BR>String url =" jdbc:sybase:Tds:localhost:5007/myDB";//myDB为你的数据库名 <BR>Properties sysProps = System.getProperties(); <BR>SysProps.put("user","userid"); <BR>SysProps.put("password","user_password"); <BR>Connection conn= DriverManager.getConnection(url, SysProps); </TD></TR></TBODY></TABLE><BR>　　5、Informix数据库 <BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#dadacf border=1>
<TBODY>
<TR>
<TD>Class.forName("com.informix.jdbc.IfxDriver").newInstance(); <BR>String url = "jdbc:informix-sqli://123.45.67.89:1533/myDB:INFORMIXSERVER=myserver; <BR>user=testuser;password=testpassword"; //myDB为数据库名 <BR>Connection conn= DriverManager.getConnection(url); </TD></TR></TBODY></TABLE><BR>　　6、MySQL数据库 <BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#dadacf border=1>
<TBODY>
<TR>
<TD>Class.forName("org.gjt.mm.mysql.Driver").newInstance(); <BR>String url ="jdbc:mysql://localhost/myDB?user=soft&amp;password=soft1234&amp;useUnicode=true&amp;characterEncoding=8859_1" <BR>//myDB为数据库名 <BR>Connection conn= DriverManager.getConnection(url); </TD></TR></TBODY></TABLE><BR>　　7、PostgreSQL数据库 <BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#dadacf border=1>
<TBODY>
<TR>
<TD>Class.forName("org.postgresql.Driver").newInstance(); <BR>String url ="jdbc:postgresql://localhost/myDB" //myDB为数据库名 <BR>String user="myuser"; <BR>String password="mypassword"; <BR>Connection conn= DriverManager.getConnection(url,user,password); </TD></TR></TBODY></TABLE><BR>　　8、access数据库直连用ODBC的<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#dadacf border=1>
<TBODY>
<TR>
<TD>Class.forName("sun.jdbc.odbc.JdbcOdbcDriver") ;<BR>String url="jdbc:odbc:Driver={MicroSoft Access Driver (*.mdb)};DBQ="+application.getRealPath("/Data/ReportDemo.mdb");<BR>Connection conn = DriverManager.getConnection(url,"","");<BR>Statement stmtNew=conn.createStatement() ;</TD></TR></TBODY></TABLE><BR>　　<B>二、JDBC连接MySql方式</B><BR><BR>　　下面是使用JDBC连接MySql的一个小的教程 <BR><BR>　　1、查找驱动程序<BR><BR>　　MySQL目前提供的java驱动程序为Connection/J，可以从MySQL官方网站下载，并找到mysql-connector-java-3.0.15-ga-bin.jar文件，此驱动程序为纯java驱动程序，不需做其他配置。<BR><BR>　　2、动态指定classpath<BR><BR>　　如果需要执行时动态指定classpath，就在执行时采用－cp方式。否则将上面的.jar文件加入到classpath环境变量中。<BR><BR>　　3、加载驱动程序<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#dadacf border=1>
<TBODY>
<TR>
<TD>try{<BR>　Class.forName(com.mysql.jdbc.Driver);<BR>　System.out.println(Success loading Mysql Driver!);<BR>}catch(Exception e)<BR>{<BR>　System.out.println(Error loading Mysql Driver!);<BR>　e.printStackTrace();<BR>}</TD></TR></TBODY></TABLE><BR>　　4、设置连接的url<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#dadacf border=1>
<TBODY>
<TR>
<TD>jdbc：mysql：//localhost/databasename[?pa=va][＆pa=va]</TD></TR></TBODY></TABLE><BR><SPAN class=f14>　　<B>三、以下列出了在使用JDBC来连接Oracle数据库时可以使用的一些技巧</B><BR><BR>　　1、在客户端软件开发中使用Thin驱动程序<BR><BR>　　在开发Java软件方面，Oracle的数据库提供了四种类型的驱动程序，二种用于应用软件、applets、servlets等客户端软件，另外二种用于数据库中的Java存储过程等服务器端软件。在客户机端软件的开发中，我们可以选择OCI驱动程序或Thin驱动程序。OCI驱动程序利用Java本地化接口（JNI），通过Oracle客户端软件与数据库进行通讯。Thin驱动程序是纯Java驱动程序，它直接与数据库进行通讯。为了获得最高的性能，Oracle建议在客户端软件的开发中使用OCI驱动程序，这似乎是正确的。但我建议使用Thin驱动程序，因为通过多次测试发现，在通常情况下，Thin驱动程序的性能都超过了OCI驱动程序。<BR><BR>　　2、关闭自动提交功能，提高系统性能<BR><BR>　　在第一次建立与数据库的连接时，在缺省情况下，连接是在自动提交模式下的。为了获得更好的性能，可以通过调用带布尔值false参数的Connection类的setAutoCommit()方法关闭自动提交功能，如下所示：<BR><BR>　　conn.setAutoCommit(false);<BR><BR>　　值得注意的是，一旦关闭了自动提交功能，我们就需要通过调用Connection类的commit()和rollback()方法来人工的方式对事务进行管理。<BR><BR>　　3、在动态SQL或有时间限制的命令中使用Statement对象<BR><BR>　　在执行SQL命令时，我们有二种选择：可以使用PreparedStatement对象，也可以使用Statement对象。无论多少次地使用同一个SQL命令，PreparedStatement都只对它解析和编译一次。当使用Statement对象时，每次执行一个SQL命令时，都会对它进行解析和编译。这可能会使你认为，使用PreparedStatement对象比使用Statement对象的速度更快。然而，我进行的测试表明，在客户端软件中，情况并非如此。因此，在有时间限制的SQL操作中，除非成批地处理SQL命令，我们应当考虑使用Statement对象。<BR><BR>　　此外，使用Statement对象也使得编写动态SQL命令更加简单，因为我们可以将字符串连接在一起，建立一个有效的SQL命令。因此，我认为，Statement对象可以使动态SQL命令的创建和执行变得更加简单。<BR><BR>　　4、利用helper函数对动态SQL命令进行格式化<BR><BR>　　在创建使用Statement对象执行的动态SQL命令时，我们需要处理一些格式化方面的问题。例如，如果我们想创建一个将名字O'Reilly插入表中的SQL命令，则必须使用二个相连的“''”号替换O'Reilly中的“'”号。完成这些工作的最好的方法是创建一个完成替换操作的helper方法，然后在连接字符串心服用公式表达一个SQL命令时，使用创建的helper方法。与此类似的是，我们可以让helper方法接受一个Date型的值，然后让它输出基于Oracle的to_date()函数的字符串表达式。<BR><BR>　　5、利用PreparedStatement对象提高数据库的总体效率<BR><BR>　　在使用PreparedStatement对象执行SQL命令时，命令被数据库进行解析和编译，然后被放到命令缓冲区。然后，每当执行同一个PreparedStatement对象时，它就会被再解析一次，但不会被再次编译。在缓冲区中可以发现预编译的命令，并且可以重新使用。在有大量用户的企业级应用软件中，经常会重复执行相同的SQL命令，使用PreparedStatement对象带来的编译次数的减少能够提高数据库的总体性能。如果不是在客户端创建、预备、执行PreparedStatement任务需要的时间长于Statement任务，我会建议在除动态SQL命令之外的所有情况下使用PreparedStatement对象。<BR><BR>　　6、在成批处理重复的插入或更新操作中使用PreparedStatement对象<BR><BR>　　如果成批地处理插入和更新操作，就能够显著地减少它们所需要的时间。Oracle提供的Statement和 CallableStatement并不真正地支持批处理，只有PreparedStatement对象才真正地支持批处理。我们可以使用addBatch()和executeBatch()方法选择标准的JDBC批处理，或者通过利用PreparedStatement对象的setExecuteBatch()方法和标准的executeUpdate()方法选择速度更快的Oracle专有的方法。要使用Oracle专有的批处理机制，可以以如下所示的方式调用setExecuteBatch()：<BR><BR>
<TABLE borderColor=#ffcc66 width="90%" align=center bgColor=#dadacf border=1>
<TBODY>
<TR>
<TD>PreparedStatement pstmt3D null;<BR>try {<BR>　((OraclePreparedStatement)pstmt).setExecuteBatch(30);<BR>　...<BR>　pstmt.executeUpdate();<BR>} </TD></TR></TBODY></TABLE><BR>　　调用setExecuteBatch()时指定的值是一个上限，当达到该值时，就会自动地引发SQL命令执行，标准的executeUpdate()方法就会被作为批处理送到数据库中。我们可以通过调用PreparedStatement类的sendBatch()方法随时传输批处理任务。<BR><BR>　　7、使用Oracle locator方法插入、更新大对象（LOB）<BR><BR>　　Oracle的PreparedStatement类不完全支持BLOB和CLOB等大对象的处理，尤其是Thin驱动程序不支持利用PreparedStatement对象的setObject()和setBinaryStream()方法设置BLOB的值，也不支持利用setCharacterStream()方法设置CLOB的值。只有locator本身中的方法才能够从数据库中获取LOB类型的值。可以使用PreparedStatement对象插入或更新LOB，但需要使用locator才能获取LOB的值。由于存在这二个问题，因此，我建议使用locator的方法来插入、更新或获取LOB的值。<BR><BR>　　8、使用SQL92语法调用存储过程<BR><BR>　　在调用存储过程时，我们可以使用SQL92或Oracle PL/SQL，由于使用Oracle PL/SQL并没有什么实际的好处，而且会给以后维护你的应用程序的开发人员带来麻烦，因此，我建议在调用存储过程时使用SQL92。<BR><BR>　　9、使用Object SQL将对象模式转移到数据库中<BR><BR>　　既然可以将Oracle的数据库作为一种面向对象的数据库来使用，就可以考虑将应用程序中的面向对象模式转到数据库中。目前的方法是创建Java bean作为伪装的数据库对象，将它们的属性映射到关系表中，然后在这些bean中添加方法。尽管这样作在Java中没有什么问题，但由于操作都是在数据库之外进行的，因此其他访问数据库的应用软件无法利用对象模式。如果利用Oracle的面向对象的技术，可以通过创建一个新的数据库对象类型在数据库中模仿其数据和操作，然后使用JPublisher等工具生成自己的Java bean类。如果使用这种方式，不但Java应用程序可以使用应用软件的对象模式，其他需要共享你的应用中的数据和操作的应用软件也可以使用应用软件中的对象模式。<BR><BR>　　10、利用SQL完成数据库内的操作<BR><BR>　　我要向大家介绍的最重要的经验是充分利用SQL的面向集合的方法来解决数据库处理需求，而不是使用Java等过程化的编程语言。<BR><BR>　　如果编程人员要在一个表中查找许多行，结果中的每个行都会查找其他表中的数据，最后，编程人员创建了独立的UPDATE命令来成批地更新第一个表中的数据。与此类似的任务可以通过在set子句中使用多列子查询而在一个UPDATE命令中完成。当能够在单一的SQL命令中完成任务，何必要让数据在网上流来流去的？我建议用户认真学习如何最大限度地发挥SQL的功能。 </SPAN><img src ="http://www.blogjava.net/Titan/aggbug/28060.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Titan/" target="_blank">Titan</a> 2006-01-15 00:02 <a href="http://www.blogjava.net/Titan/articles/28060.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Java操作Excel完美解决方案</title><link>http://www.blogjava.net/Titan/articles/23051.html</link><dc:creator>Titan</dc:creator><author>Titan</author><pubDate>Thu, 08 Dec 2005 15:03:00 GMT</pubDate><guid>http://www.blogjava.net/Titan/articles/23051.html</guid><wfw:comment>http://www.blogjava.net/Titan/comments/23051.html</wfw:comment><comments>http://www.blogjava.net/Titan/articles/23051.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Titan/comments/commentRss/23051.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Titan/services/trackbacks/23051.html</trackback:ping><description><![CDATA[　只要有表格，就会有Microsoft Excel，用Microsoft Excel处理数据已成为不少人的习惯。Jakarta POI API就为Java程序员提供了一条存取Microsoft文档格式的神奇之路，其中最成熟的就是能存取Microsoft Excel文档的HSSF API。<BR><BR><IFRAME align=right marginWidth=0 marginHeight=0 src="http://images.chinabyte.com/adjs/iframe-pip/y-software-pip.html" frameBorder=0 width=360 scrolling=no height=300></IFRAME>　　本篇文章就举例示范如何利用Java 创建和读取Excel文档，并设置单元格的字体和格式。 <BR><BR>　　为了保证示例程序的运行，必须安装Java 2 sdk1.4.0 和Jakarta POI，Jakarta POI的<A class=bluekey href="http://www.yesky.com/key/265/170265.html" target=_blank>Web</A>站点是: http://jakarta.apache.org/poi/ <BR><BR>　　<B>创建Excel 文档</B><BR><BR>　　示例1将演示如何利用Jakarta POI API 创建Excel 文档。 <BR><BR>　　示例1程序如下：<BR><BR>
<TABLE width="100%" bgColor=#ffffff>
<TBODY>
<TR>
<TD>import org.apache.poi.hssf.usermodel.HSSFWorkbook;<BR>import org.apache.poi.hssf.usermodel.HSSFSheet;<BR>import org.apache.poi.hssf.usermodel.HSSFRow;<BR>import org.apache.poi.hssf.usermodel.HSSFCell;<BR>import java.io.FileOutputStream;<BR>public class CreateXL {<BR><BR>　/** Excel 文件要存放的位置，假定在D盘JTest目录下*/<BR><BR>　public static String outputFile="D:/JTest/ gongye.xls";<BR><BR>　public static void main(String argv[]){<BR><BR>　try{<BR><BR>　　// 创建新的Excel 工作簿<BR><BR>　　HSSFWorkbook workbook = new HSSFWorkbook();<BR><BR>　　// 在Excel工作簿中建一工作表，其名为缺省值<BR>　　　　　　// 如要新建一名为"效益指标"的工作表，其语句为：<BR>　　　　　　// HSSFSheet sheet = workbook.createSheet("效益指标");<BR><BR>　　HSSFSheet sheet = workbook.createSheet();<BR><BR>　　// 在索引0的位置创建行（最顶端的行）<BR><BR>　　HSSFRow row = sheet.createRow((short)0);<BR><BR>　　//在索引0的位置创建单元格（左上端）<BR>　　HSSFCell <A class=bluekey href="http://www.yesky.com/key/3971/168971.html" target=_blank>cell</A> = row.createCell((short) 0);<BR>　　// 定义单元格为字符串类型<BR>　　cell.setCellType(HSSFCell.CELL_TYPE_STRING);<BR>　　// 在单元格中输入一些内容<BR>　　cell.setCellValue("增加值");<BR>　　// 新建一输出文件流<BR>　　FileOutputStream fOut = new FileOutputStream(outputFile);<BR>　　// 把相应的Excel 工作簿存盘<BR>　　workbook.write(fOut);<BR>　　fOut.flush();<BR>　　// 操作结束，关闭文件<BR>　　fOut.close();<BR>　　System.out.println("文件生成...");<BR><BR>　}catch(Exception e) {<BR>　　System.out.println("已运行 xlCreate() : " + e );<BR>　}<BR>}<BR>}</TD></TR></TBODY></TABLE><BR>　　<B>读取Excel文档中的数据</B><BR><BR>　　示例2将演示如何读取Excel文档中的数据。假定在D盘JTest目录下有一个文件名为gongye.xls的Excel文件。<BR><BR>　　示例2程序如下：<BR><BR>
<TABLE width="100%" bgColor=#ffffff>
<TBODY>
<TR>
<TD>import org.apache.poi.hssf.usermodel.HSSFWorkbook;<BR>import org.apache.poi.hssf.usermodel.HSSFSheet;<BR>import org.apache.poi.hssf.usermodel.HSSFRow;<BR>import org.apache.poi.hssf.usermodel.HSSFCell;<BR>import java.io.FileInputStream;<BR>public class ReadXL {<BR>　/** Excel文件的存放位置。注意是正斜线*/<BR>　public static String fileToBeRead="D:/JTest/ gongye.xls";<BR>　public static void main(String argv[]){ <BR>　try{<BR>　　// 创建对Excel工作簿文件的引用<BR>　　HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(fileToBeRead));<BR>　　// 创建对工作表的引用。<BR>　　// 本例是按名引用（让我们假定那张表有着缺省名"Sheet1"）<BR>　　HSSFSheet sheet = workbook.getSheet("Sheet1");<BR>　　// 也可用getSheetAt(int index)按索引引用，<BR>　　// 在Excel文档中，第一张工作表的缺省索引是0，<BR>　　// 其语句为：HSSFSheet sheet = workbook.getSheetAt(0);<BR>　　// 读取左上端单元<BR>　　HSSFRow row = sheet.getRow(0);<BR>　　HSSFCell cell = row.getCell((short)0);<BR>　　// 输出单元内容，cell.getStringCellValue()就是取所在单元的值<BR>　　System.out.println("左上端单元是： " + cell.getStringCellValue()); <BR>　}catch(Exception e) {<BR>　　System.out.println("已运行xlRead() : " + e );<BR>　}<BR>}<BR>}</TD></TR></TBODY></TABLE><BR>　　<B>设置单元格格式</B><BR><BR>　　在这里，我们将只介绍一些和格式设置有关的语句，我们假定workbook就是对一个工作簿的引用。在Java中，第一步要做的就是创建和设置字体和单元格的格式，然后再应用这些格式：<BR><BR>　　1、创建字体，设置其为红色、粗体：<BR><BR>
<TABLE width="100%" bgColor=#ffffff>
<TBODY>
<TR>
<TD>HSSFFont font = workbook.createFont();<BR>font.setColor(HSSFFont.COLOR_RED);<BR>font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);</TD></TR></TBODY></TABLE><BR>　　2、创建格式<BR><BR>
<TABLE width="100%" bgColor=#ffffff>
<TBODY>
<TR>
<TD>HSSFCellStyle cellStyle= workbook.createCellStyle();<BR>cellStyle.setFont(font);</TD></TR></TBODY></TABLE><BR>　　3、应用格式 <BR><BR>
<TABLE width="100%" bgColor=#ffffff>
<TBODY>
<TR>
<TD>HSSFCell cell = row.createCell((short) 0);<BR>cell.setCellStyle(cellStyle);<BR>cell.setCellType(HSSFCell.CELL_TYPE_STRING);<BR>cell.setCellValue("标题 ");</TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/Titan/aggbug/23051.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Titan/" target="_blank">Titan</a> 2005-12-08 23:03 <a href="http://www.blogjava.net/Titan/articles/23051.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>