﻿<?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-study</title><link>http://www.blogjava.net/xixidabao/</link><description /><language>zh-cn</language><lastBuildDate>Tue, 12 May 2026 23:00:15 GMT</lastBuildDate><pubDate>Tue, 12 May 2026 23:00:15 GMT</pubDate><ttl>60</ttl><item><title>mysql数据导入导出总结</title><link>http://www.blogjava.net/xixidabao/archive/2009/10/23/299487.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Fri, 23 Oct 2009 07:53:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2009/10/23/299487.html</guid><description><![CDATA[<p>mysql文件导入导出有2种方式：<br />
1. 导入导出操作SQL文件，通过执行SQL语句来完成操作，文件中包含建表语句和一系列的插入语句；<br />
2. 导入导出操作特定格式的文本数据，该方式文件中仅包含数据，注意文件的编码和数据库编码要兼容,文件编码应该和character_set_database一致,而与set names charaset的charset无任何关系；<br />
<br />
这里只是方式2的操作方法：<br />
导出到文件：<br />
select * from custom into outfile 'e:\custom.txt' FIELDS TERMINATED BY ',' optionally enclosed by '"';</p>
<p>从文件导入：&nbsp;<br />
load data infile 'e:\custom.txt' replace into table custom;</p>
<p>&nbsp;load data infile 'e:\custom.txt' replace into table custom fields terminated by ',' optionally enclosed by '"';<br />
</p>
<p><br />
从库中其他表导入：<br />
&nbsp;insert into tablename1 select * from tablename2;<br />
<br />
///////////// 导入导出给定列 ///////////</p>
<p>&nbsp;load data infile 'e:\custom.txt' replace into table custom fields terminated by ',' optionally enclosed by </p>
<p>'"'(customid,name,sex);</p>
<p>&nbsp;select customid,name,sex from custom into outfile 'e:\acustom.txt' fields terminated by ',' optionally enclosed </p>
<p>by '"';</p>
<p>////////////////////////</p>
<p>MYSQL的主键是放主存的，第一次的时候执行max获取最大编号，如果插入的时候没有就自增，如果插入的时候指定了主键，则判</p>
<p>断是否大于max，是则设置主键为max，并插入记录，否则替换或出错;如果自增主键为null，则仍是自增;<br />
所以导入的时候，自增主键也可以直接导入；<br />
<br />
如果导入的时候出现：truncated字样，则是SQL_MODE问题，修改sql_mode就可以了;<br />
<br />
show variables like '%sql_mode%';<br />
set sql_mode='no_auto_create_user,no_engine_substitution';</p>
<p>如出现错误：ERROR 1262 (01000): Row 6737 was truncated; it contained more data than there were input columns.<br />
如：文件中出现,,空字符，正常情况下会出错，需要修改sql_mode后才能导入(会有正常警告)；</p>
<img src ="http://www.blogjava.net/xixidabao/aggbug/299487.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2009-10-23 15:53 <a href="http://www.blogjava.net/xixidabao/archive/2009/10/23/299487.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解析表达式</title><link>http://www.blogjava.net/xixidabao/archive/2009/04/08/264538.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Wed, 08 Apr 2009 14:16:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2009/04/08/264538.html</guid><description><![CDATA[<p>package com.sunyard.lmas.expression;</p>
<p>import java.util.ArrayList;<br />
import java.util.Iterator;<br />
import java.util.StringTokenizer;</p>
<p>import com.sunyard.lmas.Base;</p>
<p>public abstract class ExpreCountAmt extends Base {<br />
&nbsp;private ArrayList&lt;String&gt; middle = new ArrayList&lt;String&gt;();// 存储中序表达式<br />
&nbsp;private ArrayList&lt;String&gt; right = new ArrayList&lt;String&gt;();// 存储右序表达式&nbsp;<br />
&nbsp;protected String getExpression(){<br />
&nbsp;&nbsp;return middle.toString();<br />
&nbsp;}<br />
&nbsp;protected String getRight(){<br />
&nbsp;&nbsp;return right.toString();<br />
&nbsp;}<br />
&nbsp;/**<br />
&nbsp; * 获取中序表达式<br />
&nbsp; */<br />
&nbsp;private void setMiddle(String expression)throws Exception{<br />
&nbsp;&nbsp;middle.clear();<br />
&nbsp;&nbsp;right.clear();<br />
&nbsp;&nbsp;expression = expression==null ? "" : expression.trim();<br />
&nbsp;&nbsp;if(expression.length()&gt;0&amp;&amp;Calculate.isOperator(expression.substring(0,1))){<br />
&nbsp;&nbsp;&nbsp;middle.add("0");<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;StringTokenizer st = new StringTokenizer(expression, "+-*/()%", true);<br />
&nbsp;&nbsp;while (st.hasMoreElements()) {<br />
&nbsp;&nbsp;&nbsp;String item = st.nextToken();<br />
&nbsp;&nbsp;&nbsp;if(Calculate.isOperator(item))<br />
//&nbsp;&nbsp;&nbsp;if(item.endsWith("+")||item.endsWith("-")||item.endsWith("*")||item.endsWith("/")||item.endsWith("(")||item.endsWith(")")||item.endsWith("%"))<br />
&nbsp;&nbsp;&nbsp;&nbsp;middle.add(item);<br />
&nbsp;&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;middle.add(getAmt(item).toString());<br />
&nbsp;&nbsp;}<br />
&nbsp;}<br />
&nbsp;/**<br />
&nbsp; * 将中序表达式转换为右序表达式<br />
&nbsp; */<br />
&nbsp;private void toRight() {<br />
&nbsp;&nbsp;if(middle.size()&lt;=0)<br />
&nbsp;&nbsp;&nbsp;return;<br />
&nbsp;&nbsp;Stacks aStack = new Stacks();<br />
&nbsp;&nbsp;String operator;<br />
&nbsp;&nbsp;int position = 0;<br />
&nbsp;&nbsp;while (true) {<br />
&nbsp;&nbsp;&nbsp;if (Calculate.isOperator((String) middle.get(position))) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;if (aStack.top == -1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|| ((String) middle.get(position)).equals("(")) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aStack.push(middle.get(position));<br />
&nbsp;&nbsp;&nbsp;&nbsp;} else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (((String) middle.get(position)).equals(")")) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!((String) aStack.top()).equals("(")) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;operator = (String) aStack.pop();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;right.add(operator);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (Calculate.priority((String) middle<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.get(position)) &lt;= Calculate<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.priority((String) aStack.top())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp; aStack.top != -1) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;operator = (String) aStack.pop();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!operator.equals("("))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;right.add(operator);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aStack.push(middle.get(position));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;} else<br />
&nbsp;&nbsp;&nbsp;&nbsp;right.add(middle.get(position));<br />
&nbsp;&nbsp;&nbsp;position++;<br />
&nbsp;&nbsp;&nbsp;if (position &gt;= middle.size())<br />
&nbsp;&nbsp;&nbsp;&nbsp;break;<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;while (aStack.top != -1) {<br />
&nbsp;&nbsp;&nbsp;operator = (String) aStack.pop();<br />
&nbsp;&nbsp;&nbsp;right.add(operator);<br />
&nbsp;&nbsp;}<br />
&nbsp;}<br />
&nbsp;/**<br />
&nbsp; * 获取结果<br />
&nbsp; * @return<br />
&nbsp; */<br />
&nbsp;private double getResult(){<br />
&nbsp;&nbsp;if(right.size()==0)<br />
&nbsp;&nbsp;&nbsp;return 0.0;<br />
&nbsp;&nbsp;String result;<br />
&nbsp;&nbsp;Stacks aStack = new Stacks();<br />
&nbsp;&nbsp;String op1, op2, is = null;<br />
&nbsp;&nbsp;Iterator&lt;String&gt; it = right.iterator();<br />
&nbsp;&nbsp;while (it.hasNext()) {<br />
&nbsp;&nbsp;&nbsp;is = (String) it.next();<br />
&nbsp;&nbsp;&nbsp;if (Calculate.isOperator(is)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;op1 = (String) aStack.pop();<br />
&nbsp;&nbsp;&nbsp;&nbsp;op2 = (String) aStack.pop();<br />
&nbsp;&nbsp;&nbsp;&nbsp;aStack.push(Calculate.twoResult(is, op1, op2));<br />
&nbsp;&nbsp;&nbsp;} else<br />
&nbsp;&nbsp;&nbsp;&nbsp;aStack.push(is);<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;result = (String) aStack.pop();<br />
&nbsp;&nbsp;return Double.parseDouble(result);<br />
&nbsp;}<br />
&nbsp;public final double getCountAmt(String expression)throws Exception{&nbsp;&nbsp;<br />
&nbsp;&nbsp;setMiddle(expression);<br />
&nbsp;&nbsp;toRight();<br />
&nbsp;&nbsp;return getResult();<br />
&nbsp;}<br />
&nbsp;public abstract Double getAmt(String subjectno)throws Exception;<br />
}<br />
</p>
<img src ="http://www.blogjava.net/xixidabao/aggbug/264538.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2009-04-08 22:16 <a href="http://www.blogjava.net/xixidabao/archive/2009/04/08/264538.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>职场新人必看：如何在三个月掌握三年的经验（转载)</title><link>http://www.blogjava.net/xixidabao/archive/2008/01/26/177926.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Sat, 26 Jan 2008 08:17:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2008/01/26/177926.html</guid><description><![CDATA[很多资料在网上都是可以找到的，只是看你具备不具备足够的信息收集与处理能力，而这个收集与处理信息的过程，也能极大的提升你的职业能力。 <br />
<br />
　　我一直有个感觉，在&#8220;模仿中成长，在创新中成功&#8221;，其实在真正的职业工作中，大多数的工作都是模仿重复，强调的是工作效率，而不是创新。对于企业而言，过度的创新必然导致过多的失败，以及效率的低下。 <br />
<br />
　　以下方式是我的成长中曾经做过的，也是我用来训练新员工的方案。你们也可以试试。 <br />
<br />
　　看到很多谈应聘技巧的帖子，其实并不实用，有菜谱并不代表能做出好菜，能不能做出好菜仍要看你天天炒，日日炒，炒出来的本事。 <br />
<br />
　　所以，我这里要强调的一点是，你收集到的任何资料都不能只是看看，而必须自己手把手，动手去整理、去归类，去建立新的结构，这个信息收集与处理的过程甚至比你最后总结成文的文字更重要。 <br />
<br />
　　何谓&#8220;学习&#8221;？学习学习，学而习，习而成习惯。光学不习，那知识还只是书上的，老师教的，不是你自己的，只有你重复练习了，经过量变，才会有质变，当你形成条件反射时，你就真正掌握这个东西了。 <br />
<br />
　　这个过程需要维持两至三个月的时间，一定要坚持下去，你会看到自己的变化的。否则，你会用你最青春的两三年来慢慢沉淀出这些你两三个月就能掌握的东西。 <br />
<br />
　　一切一切，其实，你们比的不是其它的东西，只是比的速度。 <br />
<br />
　　这也是为什么我那么强调基本功的原因。 <br />
　　　　 <br />
　　　　 <br />
　　　　1. 职业分析： <br />
　　　　A. 分析性格——分析长处和短处——分析大家都有的长处——确定自己最终发展的专业 <br />
　　　　B. 确定兴趣——分析竞争的激烈程度和发展的空间大小——寻找相对优势—确定自己最终进入的行业 <br />
　　　　C. 确定行业内自己的专业方向，继续保持自身的专业优势。 <br />
　　　　 /* 性格决定专业，兴趣决定行业，行业&gt;专业，某个行业会包括很多专业。 */ <br />
<br />
　　　　2. 编写行业报告——着重对行业全面性的把握。 <br />
　　　　A. 通过上网查询和购买行业报刊，收集不少于三十万字的行业、重点企业的有效资料，在电脑中进行资料分析、分类、汇总。 <br />
　　　　B. 参考同类行业书籍，确定写作提纲，确定文章结构和逻辑方向，培养文字表达能力和逻辑能力，以及熟练的电脑使用技能。 <br />
　　　　C. 将三十万字资料浓缩成十至十五万字，写成一本符合出版行文格式要求的行业报告。如果选题好，还真的有出版的可能性。如果有一定的独特见解，也可以写成文章争取在专业刊物上发表，树立个人专业形象。 <br />
　　　　 <br />
　　　　3. 编写讲座报告——着重对专业系统性的把握。 <br />
　　　　A. 根据你希望从事的专业岗位，从报告中选择两到三个重点，将书稿压缩成两万字的讲座稿（按每分钟150字的演讲速度，即两个小时）。 <br />
　　　　B. 将演讲稿再浓缩成两千字的提纲和重要内容，使用PPT软件编成演讲用演示文件，并根据相关内容配以精彩图片。 <br />
　　　　C. 培养职业化的公众表达能力和表达方式，练习普通话，使用讲座稿进行互动讲座和演讲练习，只到脱口而出。 <br />
　　　　 <br />
<br />
　　告诉大家两个名人是这么成长的． <br />
　　 <br />
　　一个是教英语的李阳，他读大学时成绩不好，英语不及格，然后他做什么去了？他跑到没人的地方大声喊英语去了． <br />
　　 <br />
　　一个是做广告的叶茂中，他卖广告卖不出去了，他跑回家写书．别人看到的和他自己说的是拿着书出版出了名，发达了．其实做过这个事的人才会知道，当他把这本书写出来时，能不能出版已经不重要的，因为他知道他变化了． <br />
　　 <br />
　　我当时也是没办法了，把所有的钱买了台电脑，在家里做了三个月这个事，三个月后的变化是惊人的，我的父母、我兼职的公司的老总，最重要的是我自己，都感觉到了自己的变化。 <br />
　　 <br />
　　完全不同了。 <br />
<br />
　　其实我写的已经不是理论了，其实什么都没有技巧的，只是多看书，然后多做，硬磕，坚持下去，刚开始觉得没变化，没感觉，很累，坚持不下去，然后做着做着，就越来越快了，然后慢慢的有变化． <br />
<br />
　　而且有意思的是，我在家呆了三个月，做的事其实根本与我所从事的工作没有一点关系．只是这三个月的训练，对于我的逻辑、结构、全局性、文字表达能力、口头表达能力有了极大的提升。 <br />
<br />
　　至于收入翻５翻，当年一个月也就八百块钱，然后做完这个训练后整个人的状态都变了，有自信了，然后写了一个方案去应聘，结果进了一家大公司，当然，开始我还不想去，因为对方只给我800/月，还要自己租房子，吃饭，觉得不好，但是对方连续四个月三次打电话找我，于是我去了，结果去了就后悔了，真正好的公司根本不在乎工资的，重要的是你自己的能力。第一个月，我就挣了八千块，我以前想都不敢想的。然后两个月就转了正，而有一个有关系的同事，呆了一年还没能转正。然后每个月的收入超过工资几倍，还有年终奖两万，出国旅游，其实也不累，我到这个家公司的同时，还到另一家广告公司兼职，呵呵，很回忆的过去。 <br />
<br />
　　现在看到太多的人谈工资，我确实不喜欢，我这几年都不和老板谈工资的，因为说出来好笑，帐面工资高了，还要多扣税． <br />
<br />
　　我只在意公司的分配方式，怎么样算提成和奖金，年薪． <br />
　　 <br />
　　上个月有一个和我同龄的名牌大学MBA来我现在所在的小公司应聘,不愿意和人事小姐谈,老板不在,我就来谈了,我说好呀,以你的资历我不能和你谈给谁做副手的问题了,我跟你谈谈公司的分配方式吧,其实我们公司普通员工的收入都不高的,长沙平均水平,只是不忙,周末休两天,工作满一年还有一个星期的年休假. <br />
　　 <br />
　　但是公司几个部门负责人还是有钱的,象我三十岁,一年18万左右的年薪,其它的我就不清楚了,有几个我一个星期才见一次的,比我还小,只怕拿得比我还多.你应该也是这样的吧. <br />
　　 <br />
　　他要求6千一个月的月薪,我说这倒不重要,重要的是公司不会给你安排业务的,你自己找业务回来,公司给你平台,给你配团队,能挣多少钱是你的本事. <br />
　　 <br />
　　我说完了,问,你有什么想法吗?他说没想法,起身走人. <br />
　　 <br />
　　太有意思了,你在长沙想拿六千一个月,你等别人找事给你做,你为什么不能自己找到项目呀?六千是底薪呀,差不多7万2千的底薪,如果是这样的,那我自己算我应该拿到二十五万以上的年薪了. <br />
　　 <br />
　　从来拿底薪和拿年薪的人就是不一样的. <br />
　　 <br />
　　如果你不敢拿年薪,你就不要想着谈什么老板给你少了. <br />
　　 <br />
　　企业是要盈利的,资本家是要剥削的.问题是,如果你是一个真正能创造价值的人,你自己所创造的价值你是可以拿到手的. <br />
　　 <br />
　　大学毕业生,如果什么经验也没有,只有知识,没有技能,能找到一个给你几百块钱,让你在这里呆着学东西的企业就应该感谢了,如果你觉得这种企业不是你所向往的,你在上大学时就老老实实努力学,少玩,多练. <br />
　　 <br />
　　我工作有一个总结,钱永远不会是目标,但是它会是结果. <br />
<br />
　　谈到职业规划，有人说过职业可以规划的，我也相信未来可以计划的，问题是，你是不是这个能不能计划出你未来的人，以及，你身边有没有熟悉你的高 人 指 点，如果没有，那你自己都不会明白你自己的未来是什么的，就象象你去做所谓的性向测试，说不定是你自己在自欺欺人了，这种事多了，没人会把自己算成一个坏人的。 <br />
<br />
　　所以重要的还是那一句话，复杂的生活简单过，简单的事情重复做。 <br />
　　 <br />
　　你是中文系的，如果你的年纪还不是很大，建议你凭你自己的能力，哪怕是工资少点，你都要进最好的广告公司，去呆上一年半载，按我说的方法偷师，基本能力提升了，慢慢的你会遇到一些贵人的，还有你会涉及一些行业，慢慢的，你会发觉你内心深处喜欢的行业。 <br />
　　 <br />
　　呵呵，特别是哦，女孩子，只有努力才能进大公司，只有进了大公司才能遇到优秀的男生。好男生都关在写字楼里上班下班加班的，呵呵。生活圈子都小的，你选择的工作圈在你努力的阶段就是你的生活圈。 <br />
<br />
　　在你的成长过程中，有五个人非常重要。 <br />
　　　　 <br />
　　第一个，导师，教练。 <br />
　　他教给你实用的技巧、一定的工作经验，而不是知识。他可以给你指明方向。 <br />
　　这个人可能是你的上司、前辈、学长。 <br />
　　　　 <br />
　　第二个，陪练，同路人。 <br />
　　任何人的成长都不是学出来的，而是学而习，习而成习惯，练出来的。在这个练的过程中，是一件很苦的过程，是一系列简单动作的重复重复再重复，由量变到质变的过程，在这个过程中，一个人很难坚持下来，这时你需要一个同路人。 <br />
　　他可以是和你共同兴趣，共同目标的朋友，最好是你生命中所爱的人。 <br />
　　　　 <br />
　　第三个，榜样，他是你人生的标杆。 <br />
　　在你一生中，在不同阶段，会有不同的标杆，你向他学习，受他鼓舞，一步一步向他靠扰。 <br />
　　最重要的是那个你看得到摸得着的人，你知道，不需要通过机遇，只需要通过努力就可以达到的榜样。 <br />
　　　　 <br />
　　第四个，敌人，看不起你的人，拒绝过你的人。 <br />
　　人不到绝境是不会有斗志的，你要证明他是错的，他会给你真正的动力。 <br />
　　　　 <br />
　　第五个，最重要的是第五个，你们觉得第五个人是你自己。 <br />
　　世界上没有救世主，任何希望当别人救世主的人不是疯子就是傻子，只有自己才可以救自己。 <br />
　　这个世界上，失败的人除了天分太差之外，只有以下几点，懒，方向不对，方法不对，没有坚持。 <br />
　　如果你自己做不到，你不要怪别人。 <br />
<br />
　　基本功是你自己的，细节所积累下来的，能让你迅速融入新环境． <br />
　　/* 人和人最终的差距就是在基本功上面，是否迅速。 */ <br />
　　 <br />
　　不知道怎么跟大家谈基本功这个问题． <br />
<br />
　　很多东西大家都没把它当基本功了． <br />
<br />
　　比如说，我想要的人，他打字很快，他很少很少写错别字，有丰富的词汇量，逻辑很清晰，用词很准确，这些看上去难不难？ <br />
　　 <br />
　　但是在我这两年见过的应聘的策划文案来看，只有两个人做到了．一个是做了三年文案的女孩子，慢慢磨的．一个是中文硕士生，还没毕业． <br />
　　 <br />
　　其实大学到底教给大家什么了？ <br />
　　知识？ <br />
　　 <br />
　　大学阶段必须打好你的基本功，这些决定了你就业后的学习能力，阶层简单工作的工作效率． <br />
　　 <br />
　　如果谁还说打字、排版是文员做的事，那只能说他是真正不明白真正的职场需要。 <br />
　　 <br />
　　你们在大学所学到的知识，都是同质化的了，如果将知识变为通用的、标准化的技能才是重要的。 <br />
　　 <br />
　　既然学的东西没用，那在大学还要不要认真学习呢？ <br />
　　 <br />
　　当然要，因为这些东西是系统性的，这个学习过程能培养你的学习能力。 <br />
　　 <br />
　　知识不能改变你的命运了，但是它可以改变你的气质。 <br />
　　 <br />
　　如果你读个四年大学出来，你的气质还不能好一点，那你的大学就真的白读了。 <br />
　　 <br />
　　经常有人在问面试穿什么衣服呀？ <br />
　　 <br />
　　穿什么衣服重要吗？ <br />
　　 <br />
　　重要的是什么人在穿这些衣服。 <br />
　　 <br />
　　重要的是你的精气神，你的气质。 <br />
　　 <br />
　　有一天有一个应聘文案的来了，我叫设计总监先和他聊聊。 <br />
　　 <br />
　　聊完了，我说这个人不行吧，设计总监说为什么？ <br />
　　 <br />
　　我说我们调性不符，我们多少都有点书卷气，而他是一脸的江湖气。 <br />
　　 <br />
　　果然，呵呵。 <br />
　　 <br />
　　招聘方当然是要看应聘者的外形条件的，但并不是丑的就不招，重要的是能力和你的气质，是不是符合公司要求的。 <br />
<br />
　　重要的是兴趣。 <br />
　　 <br />
　　然后是狂练基本功，简单重复积累。 <br />
　　 <br />
　　学打拳，你先站三个月桩再说。 <br />
　　 <br />
　　面对新人，我说很多东西，你会发现，每个字你都认识，每句话你都看得懂，但是你理解吗？ <br />
　　 <br />
　　领悟，是教不了的。 <br />
　　 <br />
　　自己努力吧，自己重复做，再会明白自己最想要的是什么。 <br />
　　 <br />
　　你考公员员如果死活考不上，那你应该去想想，这种机械性的考试你都过不了，那是不是学习方法，或者兴趣不对呀？ <br />
　　 <br />
　　做销售，同样的，从基阶做起吧。 <br />
　　 <br />
　　你的财政学对你有没有帮助？ <br />
　　 <br />
　　当然有，你对销售的认识会不同的。 <br />
　　 <br />
　　象十年前我卖保险，人人都跟银行比，算利息，都算得没有银行高，只能说死了人有赔了。 <br />
　　 <br />
　　而我是怎么算呢？我用递增，还是增减年金公式算，呵呵，比银行高呢。 <br />
　　 <br />
　　另外，别人说死了人有赔，最多是说得婉转点。 <br />
　　 <br />
　　我可没把它当死人卖呀，我把它当礼物卖，当成父母送给孩子的礼物卖，卖得可好了，呵呵。 <br />
　　 <br />
　　现在哪个做人寿险的人敢说他一年做两百多单？ <br />
　　 <br />
　　呵呵，我好象一年做了二百四十单左右，全是年缴哦。 <br />
<br />
　　这个世界上最穷的和最富的人都在做销售． <br />
　　 <br />
　　做销售的人底薪很低的，大多数人拼的只是体力罢了，如果你想做好，你多花心思就可以了．多想多跑，还是在一个行业里多坚持，找到高手做师父带你． <br />
<br />
　　我说说当年我混日子的时候怎么过来的． <br />
　　 <br />
　　那年头电脑还紧俏，我只要一有机会就到别人电脑上练东西，终于练成了今天的电脑基本功，一方面要多学，一方面要多用心． <br />
　　 <br />
　　然后，我每天做记录，记下工作的流程，记下别人说过的工作中重要的话，其实什么叫行业经验，很多老手随便说的话，都是行话了，有它的意思的，听了就要想，就要去查，很多东西就知道了． <br />
　　 <br />
　　为什么要记录，因为什么叫职业化？职业化就是标准化、流程化，模式化，你多看多记多想就能明白了，这些东西在很多地方都是通用的。 <br />
　　/* 职业精神 */ <br />
<br />
　　有一点，如果这里收入还可以的话，你好好学吧，任何工作都要呆一两年，你才会有认识的，跳来跳去的对你不好，真的，你还在磨性情的时候，只要你保持学习的能力，别下班玩去了就可以了，有压力才有动力，好好留心心仪的公司招聘的要求，按那个要求去做一个一年的训练与学习计划，一年后，那个公司在等你。
<img src ="http://www.blogjava.net/xixidabao/aggbug/177926.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2008-01-26 16:17 <a href="http://www.blogjava.net/xixidabao/archive/2008/01/26/177926.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MessageDigest对密码进行加密</title><link>http://www.blogjava.net/xixidabao/archive/2008/01/26/177892.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Sat, 26 Jan 2008 04:16:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2008/01/26/177892.html</guid><description><![CDATA[时候，我们必须把用户密码存放到数据库，为了安全起见，我们需要对这些密码进行单向的加密处理，<br />
比如，有明文密码如下：<br />
String originalPwd = "mypassword";
<p>应用报文摘要方法，得到单向的加密字符串 </p>
<p>//MD5是16位,SHA是20位（这是两种报文摘要的算法）<br />
//MessageDigest md= MessageDigest.getInstance("MD5");<br />
MessageDigest messageDigest=MessageDigest.getInstance("SHA-1");<br />
messageDigest.update(originalPwd.getBytes());<br />
//String digestedPwdString = new String(messageDigest.digest());<br />
String digestedPwdString = new String(Base64.encode(messageDigest.digest()));<br />
System.out.println("pwd:" + digestedPwdString);<br />
这样，就得到密码的报文摘要，把此摘要保存到数据库，<br />
以后用户登陆时，用相同的算法算出摘要，和数据库中的比较，如果一致，则密码正确。 </p>
<p>注意：<br />
byte[] digest = messageDigest.digest();<br />
得到的是个二进制byte数组，有可能某些byte是不可打印的字符。<br />
所以用Base64.encode把它转化成可打印字符。 </p>
<p>也可以把digest的每个byte转化成hex（16进制）保存。<br />
MessageDigest messageDigest=MessageDigest.getInstance("SHA-1");<br />
messageDigest.update(originalPwd.getBytes());<br />
byte[] bin = messageDigest.digest()；<br />
再调用下面的方法生产hex（16进制）保存。 </p>
<p><br />
二行制转hex字符串的方法如下：<br />
private static String byte2hex(byte[] b){<br />
&nbsp;&nbsp;&nbsp; String hs="";<br />
&nbsp;&nbsp;&nbsp; String stmp="";<br />
&nbsp;&nbsp;&nbsp; for (int n=0; n&lt;b.length; n++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stmp=(java.lang.Integer.toHexString(b[n] &amp; 0xFF));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (stmp.length()==1) hs=hs+"0"+stmp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else hs=hs+stmp;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; return hs;<br />
} </p>
<p>或者：<br />
private static String byto2hex2(byte[] bin){<br />
&nbsp;&nbsp;&nbsp; StringBuffer buf = new StringBuffer();<br />
&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; bin.length; ++i) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int x = bin[i] &amp; 0xFF, h = x &gt;&gt;&gt; 4, l = x &amp; 0x0F;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf.append((char) (h + ((h &lt; 10) ? '0' : 'a' - 10)));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf.append((char) (l + ((l &lt; 10) ? '0' : 'a' - 10)));<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; return buf.toString();<br />
} </p>
<p>或者:<br />
干脆直接用下面的方法生成，用到第三方包：<br />
public static String encryptPwd(String pwd, String algorithm){<br />
&nbsp;&nbsp;&nbsp; //String a = org.apache.catalina.realm.RealmBase.Digest(pwd,"SHA-1");<br />
&nbsp;&nbsp;&nbsp; return org.apache.catalina.realm.RealmBase.Digest(pwd, algorithm);<br />
}</p>
&nbsp; <br />
<br />
http://www.ibm.com/developerworks/cn/java/l-security/index.html
<img src ="http://www.blogjava.net/xixidabao/aggbug/177892.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2008-01-26 12:16 <a href="http://www.blogjava.net/xixidabao/archive/2008/01/26/177892.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java NIO API详解</title><link>http://www.blogjava.net/xixidabao/archive/2008/01/18/176208.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Fri, 18 Jan 2008 06:47:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2008/01/18/176208.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Java NIO API详解&nbsp;&nbsp;&nbsp;&nbsp; 选择自 DaiJiaLin 的 Blog &nbsp;在JDK 1.4以前，Java的IO操作集中在java.io这个包中，是基于流的同步（blocking）API。对于大多数应用来说，这样的API使用很方便，然而，一些对性能要求较高的应用，尤其是服务端应用，往往需要一个更为有效的方式来处理IO。从JDK 1.4...&nbsp;&nbsp;<a href='http://www.blogjava.net/xixidabao/archive/2008/01/18/176208.html'>阅读全文</a><img src ="http://www.blogjava.net/xixidabao/aggbug/176208.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2008-01-18 14:47 <a href="http://www.blogjava.net/xixidabao/archive/2008/01/18/176208.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SQL语句处理的过程</title><link>http://www.blogjava.net/xixidabao/archive/2007/12/20/169007.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Thu, 20 Dec 2007 05:30:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2007/12/20/169007.html</guid><description><![CDATA[在调整之前我们需要了解一些背景知识，只有知道这些背景知识，我们才能更好的去调整sql语句。<br />
本节介绍了SQL语句处理的基本过程，主要包括：<br />
　　&#183;&nbsp; &nbsp; &nbsp; &nbsp; 查询语句处理 <br />
　　&#183;&nbsp; &nbsp; &nbsp; &nbsp; DML语句处理(insert, update, delete) <br />
　　&#183;&nbsp; &nbsp; &nbsp; &nbsp; DDL 语句处理(create .. , drop .. , alter .. , ) <br />
　　&#183;&nbsp; &nbsp; &nbsp; &nbsp; 事务控制(commit, rollback) <br />
<br />
<strong>　　SQL 语句的执行过程(SQL Statement Execution)</strong><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
　　 图3-1 概要的列出了处理和运行一个sql语句的需要各个重要阶段。在某些情况下，Oracle运行sql的过程可能与下面列出的各个阶段的顺序有所不同。如DEFINE阶段可能在FETCH阶段之前，这主要依赖你如何书写代码。<br />
<br />
　　对许多oracle的工具来说，其中某些阶段会自动执行。绝大多数用户不需要关心各个阶段的细节问题，然而，知道执行的各个阶段还是有必要的，这会帮助你写出更高效的SQL语句来，而且还可以让你猜测出性能差的SQL语句主要是由于哪一个阶段造成的，然后我们针对这个具体的阶段，找出解决的办法。<br />
<br />
　　图 3-1&nbsp;&nbsp;SQL语句处理的各个阶段<br />
<br />
<strong>　　DML语句的处理</strong><br />
&nbsp; &nbsp;&nbsp; &nbsp;<br />
　　本节给出一个例子来说明在DML语句处理的各个阶段到底发生了什么事情。假设你使用Pro*C程序来为指定部门的所有职员增加工资。程序已经连到正确的用户，你可以在你的程序中嵌入如下的SQL语句：<br />
EXEC SQL UPDATE employees <br />
SET salary = 1.10 * salary&nbsp;WHERE department_id = :var_department_id; var_department_id是程序变量，里面包含部门号，我们要修改该部门的职员的工资。当这个SQL语句执行时，使用该变量的值。<br />
<br />
　　每种类型的语句都需要如下阶段：<br />
　　&#183;&nbsp; &nbsp; &nbsp; &nbsp; 第1步: Create a Cursor&nbsp; &nbsp;&nbsp;&nbsp;创建游标<br />
　　&#183;&nbsp; &nbsp; &nbsp; &nbsp; 第2步: Parse the Statement&nbsp;&nbsp;分析语句<br />
　　&#183;&nbsp; &nbsp; &nbsp; &nbsp; 第5步: Bind Any Variables&nbsp; &nbsp; 绑定变量<br />
　　&#183;&nbsp; &nbsp; &nbsp; &nbsp; 第7步: Run the Statement&nbsp; &nbsp; 运行语句<br />
　　&#183;&nbsp; &nbsp; &nbsp; &nbsp; 第9步: Close the Cursor&nbsp; &nbsp;&nbsp;&nbsp;关闭游标<br />
<br />
　　如果使用了并行功能，还会包含下面这个阶段：<br />
　　&#183;&nbsp; &nbsp; &nbsp; &nbsp; 第6步: Parallelize the Statement&nbsp; &nbsp;并行执行语句<br />
<br />
　　如果是查询语句，则需要以下几个额外的步骤，如图 3所示：<br />
　　&#183;&nbsp; &nbsp; &nbsp; &nbsp; 第3步: Describe Results of a Query&nbsp; &nbsp;描述查询的结果集<br />
　　&#183;&nbsp; &nbsp; &nbsp; &nbsp; 第4步: Define Output of a Query&nbsp; &nbsp;&nbsp; &nbsp;定义查询的输出数据<br />
　　&#183;&nbsp; &nbsp; &nbsp; &nbsp; 第8步: Fetch Rows of a Query&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;取查询出来的行<br />
<br />
　　下面具体说一下每一步中都发生了什么事情：.<br />
<strong><br />
　　第1步: 创建游标(Create a Cursor)</strong><br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;由程序接口调用创建一个游标（cursor）。任何SQL语句都会创建它，特别在运行DML语句时，都是自动创建游标的，不需要开发人员干预。多数应用中，游标的创建是自动的。然而，在预编译程序(pro*c)中游标的创建，可能是隐含的，也可能显式的创建。在存储过程中也是这样的。<br />
<br />
<strong>　　第2步:分析语句(Parse the Statement)</strong><br />
&nbsp;<br />
　　在语法分析期间，SQL语句从用户进程传送到Oracle，SQL语句经语法分析后，SQL语句本身与分析的信息都被装入到共享SQL区。在该阶段中，可以解决许多类型的错误。<br />
<br />
　　语法分析分别执行下列操作：<br />
l&nbsp; &nbsp; &nbsp; &nbsp; 翻译SQL语句，验证它是合法的语句，即书写正确<br />
l&nbsp; &nbsp; &nbsp; &nbsp; 实现数据字典的查找，以验证是否符合表和列的定义<br />
l&nbsp; &nbsp; &nbsp; &nbsp; 在所要求的对象上获取语法分析锁，使得在语句的语法分析过程中不改变这些对象的定义<br />
l&nbsp; &nbsp; &nbsp; &nbsp; 验证为存取所涉及的模式对象所需的权限是否满足<br />
l&nbsp; &nbsp; &nbsp; &nbsp; 决定此语句最佳的执行计划<br />
l&nbsp; &nbsp; &nbsp; &nbsp; 将它装入共享SQL区<br />
l&nbsp; &nbsp; &nbsp; &nbsp; 对分布的语句来说，把语句的全部或部分路由到包含所涉及数据的远程节点<br />
&nbsp; &nbsp;&nbsp; &nbsp;<br />
　　以上任何一步出现错误，都将导致语句报错，中止执行。<br />
<br />
　　只有在共享池中不存在等价SQL语句的情况下，才对SQL语句作语法分析。在这种情况下，数据库内核重新为该语句分配新的共享SQL区，并对语句进行语法分析。进行语法分析需要耗费较多的资源，所以要尽量避免进行语法分析，这是优化的技巧之一。<br />
<br />
　　语法分析阶段包含了不管此语句将执行多少次，而只需分析一次的处理要求。Oracle只对每个SQL语句翻译一次，在以后再次执行该语句时，只要该语句还在共享SQL区中，就可以避免对该语句重新进行语法分析，也就是此时可以直接使用其对应的执行计划对数据进行存取。这主要是通过绑定变量(bind variable)实现的，也就是我们常说的共享SQL，后面会给出共享SQL的概念。<br />
<br />
　　虽然语法分析验证了SQL语句的正确性，但语法分析只能识别在SQL语句执行之前所能发现的错误(如书写错误、权限不足等)。因此，有些错误通过语法分析是抓不到的。例如，在数据转换中的错误或在数据中的错（如企图在主键中插入重复的值）以及死锁等均是只有在语句执行阶段期间才能遇到和报告的错误或情况。<br />
<br />
<strong>　　查询语句的处理</strong><br />
&nbsp; &nbsp;&nbsp; &nbsp;<br />
　　查询与其它类型的SQL语句不同，因为在成功执行后作为结果将返回数据。其它语句只是简单地返回成功或失败，而查询则能返回一行或许多行数据。查询的结果均采用表格形式，结果行被一次一行或者批量地被检索出来。从这里我们可以得知批量的fetch数据可以降低网络开销，所以批量的fetch也是优化的技巧之一。<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp; 有些问题只与查询处理相关，查询不仅仅指SELECT语句，同样也包括在其它SQL语句中的隐含查询。例如，下面的每个语句都需要把查询作为它执行的一部分：<br />
INSERT INTO table SELECT... <br />
UPDATE table SET x = y WHERE... <br />
DELETE FROM table WHERE... <br />
CREATE table AS SELECT... <br />
<br />
　　具体来说，查询<br />
&#183;&nbsp; &nbsp; &nbsp; &nbsp; 要求读一致性<br />
&#183;&nbsp; &nbsp; &nbsp; &nbsp; 可能使用回滚段作中间处理<br />
&#183;&nbsp; &nbsp; &nbsp; &nbsp; 可能要求SQL语句处理描述、定义和取数据阶段<br />
<br />
<strong>　　第3步: 描述查询结果(Describe Results of a Query)</strong><br />
&nbsp;<br />
　　描述阶段只有在查询结果的各个列是未知时才需要；例如，当查询由用户交互地输入需要输出的列名。在这种情况要用描述阶段来决定查询结果的特征（数据类型，长度和名字）。<br />
<br />
<strong>　　第4步: 定义查询的输出数据(Define Output of a Query)&nbsp;&nbsp;</strong><br />
&nbsp; &nbsp;&nbsp; &nbsp; <br />
　　在查询的定义阶段，你指定与查询出的列值对应的接收变量的位置、大小和数据类型，这样我们通过接收变量就可以得到查询结果。如果必要的话，Oracle会自动实现数据类型的转换。这是将接收变量的类型与对应的列类型相比较决定的。<br />
<br />
<strong>　　第5步: 绑定变量(Bind Any Variables)</strong><br />
&nbsp; &nbsp;&nbsp; &nbsp;<br />
　　此时，Oracle知道了SQL语句的意思，但仍没有足够的信息用于执行该语句。Oracle 需要得到在语句中列出的所有变量的值。在该例中，Oracle需要得到对department_id列进行限定的值。得到这个值的过程就叫绑定变量(binding variables)<br />
<br />
　　此过程称之为将变量值捆绑进来。程序必须指出可以找到该数值的变量名（该变量被称为捆绑变量，变量名实质上是一个内存地址，相当于指针）。应用的最终用户可能并没有发觉他们正在指定捆绑变量，因为Oracle 的程序可能只是简单地指示他们输入新的值，其实这一切都在程序中自动做了。因为你指定了变量名，在你再次执行之前无须重新捆绑变量。你可以改变绑定变量的值，而Oracle在每次执行时，仅仅使用内存地址来查找此值。如果Oracle 需要实现自动数据类型转换的话（除非它们是隐含的或缺省的），你还必须对每个值指定数据类型和长度。关于这些信息可以参考oracle的相关文档，如Oracle Call Interface Programmer's Guide<br />
<br />
<strong>　　第6步: 并行执行语句(Parallelize the Statement )</strong><br />
&nbsp; &nbsp;&nbsp;&nbsp;<br />
　　ORACLE 可以在SELECTs, INSERTs, UPDATEs, MERGEs, DELETEs语句中执行相应并行查询操作，对于某些DDL操作，如创建索引、用子查询创建表、在分区表上的操作，也可以执行并行操作。并行化可以导致多个服务器进程(oracle server processes)为同一个SQL语句工作，使该SQL语句可以快速完成，但是会耗费更多的资源，所以除非很有必要，否则不要使用并行查询。<br />
<br />
<strong>　　第7步: 执行语句(Run the Statement)</strong><br />
&nbsp; &nbsp;&nbsp; &nbsp;<br />
　　到了现在这个时候，Oracle拥有所有需要的信息与资源，因此可以真正运行SQL语句了。如果该语句为SELECT查询或INSERT语句，则不需要锁定任何行，因为没有数据需要被改变。然而，如果语句为UPDATE或DELETE语句，则该语句影响的所有行都被锁定，防止该用户提交或回滚之前，别的用户对这些数据进行修改。这保证了数据的一致性。对于某些语句，你可以指定执行的次数，这称为批处理(array processing)。指定执行N次，则绑定变量与定义变量被定义为大小为N的数组的开始位置，这种方法可以减少网络开销，也是优化的技巧之一。<br />
<br />
<strong>　　第8步: 取出查询的行(Fetch Rows of a Query)</strong><br />
&nbsp; &nbsp;&nbsp; &nbsp;<br />
　　在fetch阶段，行数据被取出来，每个后续的存取操作检索结果集中的下一行数据，直到最后一行被取出来。上面提到过，批量的fetch是优化的技巧之一。<br />
<br />
<strong>　　第9步: 关闭游标(Close the Cursor)</strong><br />
&nbsp; &nbsp;&nbsp; &nbsp;<br />
　　SQL语句处理的最后一个阶段就是关闭游标<br />
<br />
<strong>　　DDL语句的处理(DDL Statement Processing)</strong><br />
&nbsp; &nbsp;&nbsp;&nbsp;<br />
　　DDL语句的执行不同与DML语句和查询语句的执行，这是因为DDL语句执行成功后需要对数据字典数据进行修改。对于DDL语句，语句的分析阶段实际上包括分析、查找数据字典信息和执行。事务管理语句、会话管理语句、系统管理语句只有分析与执行阶段，为了重新执行该语句，会重新分析与执行该语句。<br />
<br />
<strong>　　事务控制(Control of Transactions)</strong><br />
&nbsp; &nbsp;&nbsp; &nbsp;<br />
　　一般来说，只有使用ORACLE编程接口的应用设计人员才关心操作的类型，并把相关的操作组织在一起，形成一个事务。一般来说，我门必须定义事务，这样在一个逻辑单元中的所有工作可以同时被提交或回滚，保证了数据的一致性。一个事务应该由逻辑单元中的所有必须部分组成，不应该多一个，也不应该少一个。<br />
　　&#183;&nbsp; &nbsp; &nbsp; &nbsp; 在事务开始和结束的这段时间内，所有被引用表中的数据都应该在一致的状态(或可以被回溯到一致的状态)<br />
　　&#183;&nbsp; &nbsp; &nbsp; &nbsp; 事务应该只包含可以对数据进行一致更改(one consistent change to the data)的SQL语句<br />
<br />
　　例如，在两个帐号之间的转帐(这是一个事务或逻辑工作单元)，应该包含从一个帐号中借钱(由一个SQL完成)，然后将借的钱存入另一个帐号(由另一个SQL完成)。这2个操作作为一个逻辑单元，应该同时成功或同时失败。其它不相关的操作，如向一个帐户中存钱，不应该包含在这个转帐事务中。<br />
<br />
　　在设计应用时，除了需要决定哪种类型的操作组成一个事务外，还需要决定使用BEGIN_DISCRETE_TRANSACTIO存储过程是否对提高小的、非分布式的事务的性能有作用。
<img src ="http://www.blogjava.net/xixidabao/aggbug/169007.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2007-12-20 13:30 <a href="http://www.blogjava.net/xixidabao/archive/2007/12/20/169007.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SQL触发器语法参考 </title><link>http://www.blogjava.net/xixidabao/archive/2007/12/07/165947.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Fri, 07 Dec 2007 01:13:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2007/12/07/165947.html</guid><description><![CDATA[<div class="postTitle"><a id="AjaxHolder_ctl01_TitleUrl" href="http://www.cnblogs.com/yesun/archive/2007/02/06/641481.html">SQL触发器语法参考</a> </div>
<div class="postText">
<p><font face="新宋体"><code>CREATE TRIGGER <em>trigger_name </em></code><br />
<code>ON { <em>table</em> | <em>view </em></code></font>}<font face="新宋体"><code> <br />
[ WITH ENCRYPTION ] <br />
{</code><br />
</font>&nbsp;&nbsp;&nbsp;&nbsp;{<code><font face="新宋体"> </font></code><strong>{<code><font face="新宋体"> </font></code></strong><code><font face="新宋体">FOR | AFTER | INSTEAD OF </font></code><strong>}</strong><font face="新宋体"><code> { [ INSERT ] [ <strong>, </strong>] [ UPDATE ] }</code><br />
</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font face="新宋体"><code>[ WITH APPEND ]</code><br />
</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font face="新宋体"><code>[ NOT FOR REPLICATION ]</code><br />
</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font face="新宋体"><code>AS</code><br />
</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font face="新宋体"><code>[ { IF UPDATE <strong>( </strong><em>column </em><strong>)</strong></code><br />
</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font face="新宋体"><code>[ { AND | OR } UPDATE <strong>( </strong><em>column </em><strong>) </strong>]</code><br />
</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font face="新宋体"><code>[ ...<em>n </em>]</code><br />
</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code><font face="新宋体">| IF <strong>(</strong> COLUMNS_UPDATED <strong>( ) </strong></font></code>{<code><font face="新宋体"> <em>bitwise_operator </em></font></code>}<font face="新宋体"><code> <em>updated_bitmask </em><strong>)</strong></code><br />
</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<code><font face="新宋体"> <em>comparison_operator </em></font></code>}<font face="新宋体"><code> <em>column_bitmask</em> [ ...<em>n </em>]</code><br />
</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<code><font face="新宋体"> ] <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<em>sql_statement</em> [<strong> </strong>...<em>n </em>] <br />
&nbsp;&nbsp;&nbsp;&nbsp;} <br />
} </font></code></p>
<h5>参数</h5>
<p><em>trigger_name</em></p>
<p class="indent">是触发器的名称。触发器名称必须符合标识符规则，并且在数据库中必须唯一。可以选择是否指定触发器所有者名称。</p>
<p><em>Table</em> | <em>view</em></p>
<p class="indent">是在其上执行触发器的表或视图，有时称为触发器表或触发器视图。可以选择是否指定表或视图的所有者名称。</p>
<p>WITH ENCRYPTION</p>
<p class="indent">加密 <strong>syscomments</strong> 表中包含 CREATE TRIGGER 语句文本的条目。使用 WITH ENCRYPTION 可防止将触发器作为 SQL Server 复制的一部分发布。</p>
<p>AFTER</p>
<p class="indent">指定触发器只有在触发 SQL 语句中指定的所有操作都已成功执行后才激发。所有的引用级联操作和约束检查也必须成功完成后，才能执行此触发器。</p>
<p class="indent">如果仅指定 FOR 关键字，则 AFTER 是默认设置。</p>
<p class="indent">不能在视图上定义 AFTER 触发器。</p>
<p>INSTEAD OF</p>
<p class="indent">指定执行触发器而不是执行触发 SQL 语句，从而替代触发语句的操作。</p>
<p class="indent">在表或视图上，每个 INSERT、UPDATE 或 DELETE 语句最多可以定义一个 INSTEAD OF 触发器。然而，可以在每个具有 INSTEAD OF 触发器的视图上定义视图。</p>
<p class="indent">INSTEAD OF 触发器不能在 WITH CHECK OPTION 的可更新视图上定义。如果向指定了 WITH CHECK OPTION 选项的可更新视图添加 INSTEAD OF 触发器，SQL Server 将产生一个错误。用户必须用 ALTER VIEW 删除该选项后才能定义 INSTEAD OF 触发器。</p>
<p>{ [DELETE] [,] [INSERT] [,] [UPDATE] }</p>
<p class="indent">是指定在表或视图上执行哪些数据修改语句时将激活触发器的关键字。必须至少指定一个选项。在触发器定义中允许使用以任意顺序组合的这些关键字。如果指定的选项多于一个，需用逗号分隔这些选项。</p>
<p class="indent">对于 INSTEAD OF 触发器，不允许在具有 ON DELETE 级联操作引用关系的表上使用 DELETE 选项。同样，也不允许在具有 ON UPDATE 级联操作引用关系的表上使用 UPDATE 选项。</p>
<p>WITH APPEND</p>
<p class="indent">指定应该添加现有类型的其它触发器。只有当兼容级别是 65 或更低时，才需要使用该可选子句。如果兼容级别是 70 或更高，则不必使用 WITH APPEND 子句添加现有类型的其它触发器（这是兼容级别设置为 70 或更高的 CREATE TRIGGER 的默认行为）。有关更多信息，请参见<strong> <a href="http://www.51windows.net/pages/ts_sp_da-di_5c8c.htm">sp_dbcmptlevel</a></strong>。</p>
<p class="indent">WITH APPEND 不能与 INSTEAD OF 触发器一起使用，或者，如果显式声明 AFTER 触发器，也不能使用该子句。只有当出于向后兼容而指定 FOR 时（没有 INSTEAD OF 或 AFTER），才能使用 WITH APPEND。以后的版本将不支持 WITH APPEND 和 FOR（将被解释为 AFTER）。</p>
<p>NOT FOR REPLICATION</p>
<p class="indent">表示当复制进程更改触发器所涉及的表时，不应执行该触发器。</p>
<p>AS</p>
<p class="indent">是触发器要执行的操作。</p>
<p><em>sql_statement</em></p>
<p class="indent">是触发器的条件和操作。触发器条件指定其它准则，以确定 DELETE、INSERT 或 UPDATE 语句是否导致执行触发器操作。</p>
<p class="indent">当尝试 DELETE、INSERT 或 UPDATE 操作时，Transact-SQL语句中指定的触发器操作将生效。</p>
<p class="indent">触发器可以包含任意数量和种类的 Transact-SQL 语句。触发器旨在根据数据修改语句检查或更改数据；它不应将数据返回给用户。触发器中的 Transact-SQL 语句常常包含控制流语言。CREATE TRIGGER 语句中使用几个特殊的表： </p>
<ul type="disc">
    <li><strong>deleted</strong> 和 <strong>inserted</strong> 是逻辑（概念）表。这些表在结构上类似于定义触发器的表（也就是在其中尝试用户操作的表）；这些表用于保存用户操作可能更改的行的旧值或新值。例如，若要检索 <strong>deleted </strong>表中的所有值，请使用：
    <pre><code>SELECT *
    FROM deleted
    </code></pre>
    <li>如果兼容级别等于 70，那么在 DELETE、INSERT 或 UPDATE 触发器中，SQL Server 将不允许引用 <strong>inserted</strong> 和 <strong>deleted</strong> 表中的 <strong>text</strong>、<strong>ntext</strong> 或 <strong>image</strong> 列。不能访问 <strong>inserted</strong> 和 <strong>deleted</strong> 表中的 <strong>text</strong>、<strong>ntext</strong> 和 <strong>image</strong> 值。若要在 INSERT 或 UPDATE 触发器中检索新值，请将 <strong>inserted</strong> 表与原始更新表联接。当兼容级别是 65 或更低时，对 <strong>inserted</strong> 或 <strong>deleted</strong> 表中允许空值的<strong>text</strong>、<strong>ntext</strong> 或 <strong>image</strong> 列，将返回空值；如果这些列不可为空，则返回零长度字符串。
    <p class="tl">当兼容级别是 80 或更高时，SQL Server 允许在表或视图上通过 INSTEAD OF 触发器更新 <strong>text</strong>、<strong>ntext</strong> 或 <strong>image</strong> 列。</p>
    </li>
</ul>
<p><em>n</em></p>
<p class="indent">是表示触发器中可以包含多条 Transact-SQL 语句的占位符。对于 IF UPDATE <strong>(</strong><em>column</em><strong>)</strong> 语句，可以通过重复 UPDATE <strong>(</strong><em>column</em><strong>) </strong>子句包含多列。</p>
<p>IF UPDATE <strong>(</strong><em>column</em><strong>)</strong></p>
<p class="indent">测试在指定的列上进行的 INSERT 或 UPDATE 操作，不能用于 DELETE 操作。可以指定多列。因为在 ON 子句中指定了表名，所以在 IF UPDATE 子句中的列名前不要包含表名。若要测试在多个列上进行的 INSERT 或 UPDATE 操作，请在第一个操作后指定单独的 UPDATE<strong>(</strong><em>column</em><strong>) </strong>子句。在 INSERT 操作中 IF UPDATE 将返回 TRUE 值，因为这些列插入了显式值或隐性 (NULL) 值。</p>
<p class="level2"></p>
<p id="Alert_Note"><strong>说明</strong>&nbsp;&nbsp;IF UPDATE <strong>(</strong><em>column</em><strong>)</strong> 子句的功能等同于 IF、IF...ELSE 或 WHILE 语句，并且可以使用 BEGIN...END 语句块。有关更多信息，请参见<a href="http://www.51windows.net/pages/ts_ca-co_0tnp.htm">控制流语言</a>。 </p>
<p>&nbsp;</p>
<p class="indent">可以在触发器主体中的任意位置使用 UPDATE (<em>column</em>)。</p>
<p><em>column</em></p>
<p class="indent">是要测试 INSERT 或 UPDATE 操作的列名。该列可以是 SQL Server 支持的任何数据类型。但是，计算列不能用于该环境中。有关更多信息，请参见<a href="http://www.51windows.net/pages/ts_da-db_7msw.htm">数据类型</a>。 </p>
<p>IF <strong>(</strong>COLUMNS_UPDATED<strong>()) </strong></p>
<p class="indent">测试是否插入或更新了提及的列，仅用于 INSERT 或 UPDATE 触发器中。COLUMNS_UPDATED 返回 <strong>varbinary</strong> 位模式，表示插入或更新了表中的哪些列。</p>
<p class="indent">COLUMNS_UPDATED 函数以从左到右的顺序返回位，最左边的为最不重要的位。最左边的位表示表中的第一列；向右的下一位表示第二列，依此类推。如果在表上创建的触发器包含 8 列以上，则 COLUMNS_UPDATED 返回多个字节，最左边的为最不重要的字节。在 INSERT 操作中 COLUMNS_UPDATED 将对所有列返回 TRUE 值，因为这些列插入了显式值或隐性 (NULL) 值。</p>
<p class="indent">可以在触发器主体中的任意位置使用 COLUMNS_UPDATED。</p>
<p><em>bitwise_operator</em></p>
<p class="indent">是用于比较运算的位运算符。</p>
<p><em>updated_bitmask</em></p>
<p class="indent">是整型位掩码，表示实际更新或插入的列。例如，表 <strong>t1 </strong>包含列 <strong>C1</strong>、<strong>C2</strong>、<strong>C3</strong>、<strong>C4</strong> 和 <strong>C5</strong>。假定表 <strong>t1</strong> 上有 UPDATE 触发器，若要检查列 <strong>C2、C3 </strong>和 <strong>C4</strong> 是否都有更新，指定值 14；若要检查是否只有列 <strong>C2</strong> 有更新，指定值 2。</p>
<p><em>comparison_operator</em></p>
<p class="indent">是比较运算符。使用等号 (=) 检查 <em>updated_bitmask</em> 中指定的所有列是否都实际进行了更新。使用大于号 (&gt;) 检查 <em>updated_bitmask </em>中指定的任一列或某些列是否已更新。</p>
<p><em>column_bitmask</em></p>
<p class="indent">是要检查的列的整型位掩码，用来检查是否已更新或插入了这些列。 </p>
<h5>注释</h5>
<p>触发器常常用于强制业务规则和数据完整性。SQL Server 通过表创建语句（ALTER TABLE 和 CREATE TABLE）提供声明引用完整性 (DRI)；但是 DRI 不提供数据库间的引用完整性。若要强制引用完整性（有关表的主键和外键之间关系的规则），请使用主键和外键约束（ALTER TABLE 和 CREATE TABLE 的 PRIMARY KEY 和 FOREIGN KEY 关键字）。如果触发器表存在约束，则在 INSTEAD OF 触发器执行之后和 AFTER 触发器执行之前检查这些约束。如果违反了约束，则回滚 INSTEAD OF 触发器操作且不执行（激发）AFTER 触发器。</p>
<p>可用 <strong>sp_settriggerorder </strong>指定表上第一个和最后一个执行的 AFTER 触发器。在表上只能为每个 INSERT、UPDATE 和 DELETE 操作指定一个第一个执行和一个最后一个执行的 AFTER 触发器。如果同一表上还有其它 AFTER 触发器，则这些触发器将以随机顺序执行。</p>
<p>如果 ALTER TRIGGER 语句更改了第一个或最后一个触发器，则将除去已修改触发器上设置的第一个或最后一个特性，而且必须用 <strong>sp_settriggerorder </strong>重置排序值。</p>
<p>只有当触发 SQL 语句（包括所有与更新或删除的对象关联的引用级联操作和约束检查）成功执行后，AFTER 触发器才会执行。AFTER 触发器检查触发语句的运行效果，以及所有由触发语句引起的 UPDATE 和 DELETE 引用级联操作的效果。</p>
<h6>触发器限制</h6>
<p>CREATE TRIGGER 必须是批处理中的第一条语句，并且只能应用到一个表中。 </p>
<p>触发器只能在当前的数据库中创建，不过触发器可以引用当前数据库的外部对象。 </p>
<p>如果指定触发器所有者名称以限定触发器，请以相同的方式限定表名。 </p>
<p>在同一条 CREATE TRIGGER 语句中，可以为多种用户操作（如 INSERT 和 UPDATE）定义相同的触发器操作。 </p>
<p>如果一个表的外键在 DELETE/UPDATE 操作上定义了级联，则不能在该表上定义 INSTEAD OF DELETE/UPDATE 触发器。</p>
<p>在触发器内可以指定任意的 SET 语句。所选择的 SET 选项在触发器执行期间有效，并在触发器执行完后恢复到以前的设置。</p>
<p>与使用存储过程一样，当触发器激发时，将向调用应用程序返回结果。若要避免由于触发器激发而向应用程序返回结果，请不要包含返回结果的 SELECT 语句，也不要包含在触发器中进行变量赋值的语句。包含向用户返回结果的 SELECT 语句或进行变量赋值的语句的触发器需要特殊处理；这些返回的结果必须写入允许修改触发器表的每个应用程序中。如果必须在触发器中进行变量赋值，则应该在触发器的开头使用 SET NOCOUNT 语句以避免返回任何结果集。 </p>
<p>DELETE 触发器不能捕获 TRUNCATE TABLE 语句。尽管 TRUNCATE TABLE 语句实际上是没有 WHERE 子句的 DELETE（它删除所有行），但它是无日志记录的，因而不能执行触发器。因为 TRUNCATE TABLE 语句的权限默认授予表所有者且不可转让，所以只有表所有者才需要考虑无意中用 TRUNCATE TABLE 语句规避 DELETE 触发器的问题。</p>
<p>无论有日志记录还是无日志记录，WRITETEXT 语句都不激活触发器。</p>
<p>触发器中不允许以下 Transact-SQL 语句：</p>
<table cols="3" cellpadding="2" rules="all" width="587" border="1" frame="box">
    <tbody>
        <tr valign="top">
            <td width="33%">ALTER DATABASE</td>
            <td width="35%">CREATE DATABASE</td>
            <td width="32%">DISK INIT</td>
        </tr>
        <tr valign="top">
            <td width="33%">DISK RESIZE</td>
            <td width="35%">DROP DATABASE</td>
            <td width="32%">LOAD DATABASE</td>
        </tr>
        <tr valign="top">
            <td width="33%">LOAD LOG</td>
            <td width="35%">RECONFIGURE</td>
            <td width="32%">RESTORE DATABASE</td>
        </tr>
        <tr valign="top">
            <td width="33%">RESTORE LOG</td>
            <td width="35%">&nbsp;</td>
            <td width="32%">&nbsp;</td>
        </tr>
    </tbody>
</table>
<br />
<p class="indent"></p>
<p id="Alert_Note"><strong>说明</strong>&nbsp;&nbsp;由于 SQL Server 不支持系统表中的用户定义触发器，因此建议不要在系统表中创建用户定义触发器。</p>
<p>&nbsp;</p>
<h6>多个触发器</h6>
<p>SQL Server 允许为每个数据修改事件（DELETE、INSERT 或 UPDATE）创建多个触发器。例如，如果对已有 UPDATE 触发器的表执行 CREATE TRIGGER FOR UPDATE，则将创建另一个更新触发器。在早期版本中，在每个表上，每个数据修改事件（INSERT、UPDATE 或 DELETE）只允许有一个触发器。 </p>
<p class="indent"></p>
<p id="Alert_Note"><strong>说明</strong>&nbsp;&nbsp;如果触发器名称不同，则 CREATE TRIGGER（兼容级别为 70）的默认行为是在现有的触发器中添加其它触发器。如果触发器名称相同，则 SQL Server 返回一条错误信息。但是，如果兼容级别等于或小于 65，则使用 CREATE TRIGGER 语句创建的新触发器将替换同一类型的任何现有触发器，即使触发器名称不同。有关更多信息，请参见<strong> </strong><a href="http://www.51windows.net/pages/ts_sp_da-di_5c8c.htm">sp_dbcmptlevel</a>。 </p>
<p>&nbsp;</p>
<h6>递归触发器</h6>
<p>当在 <strong>sp_dboption</strong> 中启用 <strong>recursive triggers</strong> 设置时，SQL Server 还允许触发器的递归调用。</p>
<p>递归触发器允许发生两种类型的递归： </p>
<ul type="disc">
    <li>间接递归<br />
    <br />
    <li>直接递归 </li>
</ul>
<p>使用间接递归时，应用程序更新表 <strong>T1</strong>，从而激发触发器 <strong>TR1</strong>，该触发器更新表 <strong>T2</strong>。在这种情况下，触发器 <strong>T2</strong> 将激发并更新 <strong>T1</strong>。</p>
<p>使用直接递归时，应用程序更新表 <strong>T1</strong>，从而激发触发器 <strong>TR1</strong>，该触发器更新表 <strong>T1</strong>。由于表 <strong>T1</strong> 被更新，触发器 <strong>TR1</strong> 再次激发，依此类推。</p>
<p>下例既使用了间接触发器递归，又使用了直接触发器递归。假定在表 <strong>T1 </strong>中定义了两个更新触发器 <strong>TR1</strong> 和 <strong>TR2</strong>。触发器 <strong>TR1</strong> 递归地更新表 <strong>T1</strong>。UPDATE 语句使 <strong>TR1</strong> 和 <strong>TR2 </strong>各执行一次。而 <strong>TR1</strong> 的执行将触发 <strong>TR1</strong>（递归）和 <strong>TR2</strong> 的执行。给定触发器的 <strong>inserted</strong> 和 <strong>deleted</strong><em> </em>表只包含与唤醒调用触发器的 UPDATE 语句相对应的行。</p>
<p class="indent"></p>
<p id="Alert_Note"><strong>说明</strong>&nbsp;&nbsp;只有启用 <strong>sp_dboption</strong> 的 <strong>recursive triggers </strong>设置，才会发生上述行为。对于为给定事件定义的多个触发器，并没有确定的执行顺序。每个触发器都应是自包含的。</p>
<p>&nbsp;</p>
<p>禁用 <strong>recursive triggers</strong> 设置只能禁止直接递归。若要也禁用间接递归，请使用 <strong>sp_configure</strong> 将 <strong>nested triggers</strong> 服务器选项设置为 0。</p>
<p>如果任一触发器执行了 ROLLBACK TRANSACTION 语句，则无论嵌套级是多少，都不会进一步执行其它触发器。</p>
<h6>嵌套触发器</h6>
<p>触发器最多可以嵌套 32 层。如果一个触发器更改了包含另一个触发器的表，则第二个触发器将激活，然后该触发器可以再调用第三个触发器，依此类推。如果链中任意一个触发器引发了无限循环，则会超出嵌套级限制，从而导致取消触发器。若要禁用嵌套触发器，请用 <strong>sp_configure </strong>将 <strong>nested triggers</strong> 选项设置为 0（关闭）。默认配置允许嵌套触发器。如果嵌套触发器是关闭的，则也将禁用递归触发器，与 <strong>sp_dboption</strong> 的 <strong>recursive triggers </strong>设置无关。</p>
<h6>延迟名称解析</h6>
<p>SQL Server 允许 Transact-SQL 存储过程、触发器和批处理引用编译时不存在的表。这种能力称为延迟名称解析。但是，如果 Transact-SQL 存储过程、触发器或批处理引用在存储过程或触发器中定义的表，则只有当兼容级别设置（通过执行 <strong>sp_dbcmptlevel </strong>设置）等于 65 时，才会在创建时发出警告。如果使用批处理，则在编译时发出警告。如果引用的表不存在，将在运行时返回错误信息。有关更多信息，请参见<a ="javascript:hhobj_1.Click()">延迟名称解析和编译</a>。 </p>
<h5>权限</h5>
<p>CREATE TRIGGER 权限默认授予定义触发器的表所有者、<strong>sysadmin</strong> 固定服务器角色成员以及 <strong>db_owner</strong> 和 <strong>db_ddladmin </strong>固定数据库角色成员，并且不可转让。</p>
<p>若要检索表或视图中的数据，用户必须在表或视图中拥有 SELECT 语句权限。若要更新表或视图的内容，用户必须在表或视图中拥有 INSERT、DELETE 和 UPDATE 语句权限。</p>
<p>如果视图中存在 INSTEAD OF 触发器，用户必须在该视图中有 INSERT、DELETE 和 UPDATE 特权，以对该视图发出 INSERT、DELETE 和 UPDATE 语句，而不管实际上是否在视图上执行了这样的操作。</p>
<h5>示例</h5>
<h6>A. 使用带有提醒消息的触发器</h6>
<p>当有人试图在 <strong>titles</strong> 表中添加或更改数据时，下例将向客户端显示一条消息。</p>
<p class="indent"></p>
<p id="Alert_Note"><strong>说明</strong>&nbsp;&nbsp;消息 50009 是 <strong>sysmessages</strong> 中的用户定义消息。有关创建用户定义消息的更多信息，请参见 <a href="http://www.51windows.net/pages/ts_sp_adda_8zdx.htm">sp_addmessage</a>。 </p>
<p>&nbsp;</p>
<pre><code>USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'reminder' AND type = 'TR')
DROP TRIGGER reminder
GO
CREATE TRIGGER reminder
ON titles
FOR INSERT, UPDATE
AS RAISERROR (50009, 16, 10)
GO
</code></pre>
<h6>B. 使用带有提醒电子邮件的触发器</h6>
<p>当 <strong>titles</strong> 表更改时，下例将电子邮件发送给指定的人员 (MaryM)。</p>
<pre><code>USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'reminder' AND type = 'TR')
DROP TRIGGER reminder
GO
CREATE TRIGGER reminder
ON titles
FOR INSERT, UPDATE, DELETE
AS
EXEC master..xp_sendmail 'MaryM',
'Don''t forget to print a report for the distributors.'
GO
</code></pre>
<h6>C. 在 employee 和 jobs 表之间使用触发器业务规则</h6>
<p>由于 CHECK 约束只能引用定义了列级或表级约束的列，表间的任何约束（在下例中是指业务规则）都必须定义为触发器。</p>
<p>下例创建一个触发器，当插入或更新雇员工作级别 (<strong>job_lvls</strong>) 时，该触发器检查指定雇员的工作级别（由此决定薪水）是否处于为该工作定义的范围内。若要获得适当的范围，必须引用 <strong>jobs</strong> 表。</p>
<pre><code>USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'employee_insupd' AND type = 'TR')
DROP TRIGGER employee_insupd
GO
CREATE TRIGGER employee_insupd
ON employee
FOR INSERT, UPDATE
AS
/* Get the range of level for this job type from the jobs table. */
DECLARE @min_lvl tinyint,
@max_lvl tinyint,
@emp_lvl tinyint,
@job_id smallint
SELECT @min_lvl = min_lvl,
@max_lvl = max_lvl,
@emp_lvl = i.job_lvl,
@job_id = i.job_id
FROM employee e INNER JOIN inserted i ON e.emp_id = i.emp_id
JOIN jobs j ON j.job_id = i.job_id
IF (@job_id = 1) and (@emp_lvl   10)
BEGIN
RAISERROR ('Job id 1 expects the default level of 10.', 16, 1)
ROLLBACK TRANSACTION
END
ELSE
IF NOT (@emp_lvl BETWEEN @min_lvl AND @max_lvl)
BEGIN
RAISERROR ('The level for job_id:%d should be between %d and %d.',
16, 1, @job_id, @min_lvl, @max_lvl)
ROLLBACK TRANSACTION
END
</code></pre>
<h6>D. 使用延迟名称解析</h6>
<p>下例创建两个触发器以说明延迟名称解析。 </p>
<pre><code>USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'trig1' AND type = 'TR')
DROP TRIGGER trig1
GO
-- Creating a trigger on a nonexistent table.
CREATE TRIGGER trig1
on authors
FOR INSERT, UPDATE, DELETE
AS
SELECT a.au_lname, a.au_fname, x.info
FROM authors a INNER JOIN does_not_exist x
ON a.au_id = x.au_id
GO
-- Here is the statement to actually see the text of the trigger.
SELECT o.id, c.text
FROM sysobjects o INNER JOIN syscomments c
ON o.id = c.id
WHERE o.type = 'TR' and o.name = 'trig1'
-- Creating a trigger on an existing table, but with a nonexistent
-- column.
USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'trig2' AND type = 'TR')
DROP TRIGGER trig2
GO
CREATE TRIGGER trig2
ON authors
FOR INSERT, UPDATE
AS
DECLARE @fax varchar(12)
SELECT @fax = phone
FROM authors
GO
-- Here is the statement to actually see the text of the trigger.
SELECT o.id, c.text
FROM sysobjects o INNER JOIN syscomments c
ON o.id = c.id
WHERE o.type = 'TR' and o.name = 'trig2'
</code></pre>
<h6>E. 使用 COLUMNS_UPDATED</h6>
<p>下例创建两个表：一个 <strong>employeeData </strong>表和一个 <strong>auditEmployeeData </strong>表。人力资源部的成员可以修改 <strong>employeeData </strong>表，该表包含敏感的雇员薪水信息。如果更改了雇员的社会保险号码 (SSN)、年薪或银行帐户，则生成审核记录并插入到 <strong>auditEmployeeData </strong>审核表。</p>
<p>通过使用 COLUMNS_UPDATED() 功能，可以快速测试对这些包含敏感雇员信息的列所做的更改。只有在试图检测对表中的前 8 列所做的更改时，COLUMNS_UPDATED() 才起作用。</p>
<pre><code>USE pubs
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'employeeData')
DROP TABLE employeeData
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'auditEmployeeData')
DROP TABLE auditEmployeeData
GO
CREATE TABLE employeeData (
emp_id int NOT NULL,
emp_bankAccountNumber char (10) NOT NULL,
emp_salary int NOT NULL,
emp_SSN char (11) NOT NULL,
emp_lname nchar (32) NOT NULL,
emp_fname nchar (32) NOT NULL,
emp_manager int NOT NULL
)
GO
CREATE TABLE auditEmployeeData (
audit_log_id uniqueidentifier DEFAULT NEWID(),
audit_log_type char (3) NOT NULL,
audit_emp_id int NOT NULL,
audit_emp_bankAccountNumber char (10) NULL,
audit_emp_salary int NULL,
audit_emp_SSN char (11) NULL,
audit_user sysname DEFAULT SUSER_SNAME(),
audit_changed datetime DEFAULT GETDATE()
)
GO
CREATE TRIGGER updEmployeeData
ON employeeData
FOR update AS
/*Check whether columns 2, 3 or 4 has been updated. If any or all of columns 2, 3 or 4 have been changed, create an audit record. The bitmask is: power(2,(2-1))+power(2,(3-1))+power(2,(4-1)) = 14. To check if all columns 2, 3, and 4 are updated, use = 14 in place of &gt;0 (below).*/
IF (COLUMNS_UPDATED() &amp; 14) &gt; 0
/*Use IF (COLUMNS_UPDATED() &amp; 14) = 14 to see if all of columns 2, 3, and 4 are updated.*/
BEGIN
-- Audit OLD record.
INSERT INTO auditEmployeeData
(audit_log_type,
audit_emp_id,
audit_emp_bankAccountNumber,
audit_emp_salary,
audit_emp_SSN)
SELECT 'OLD',
del.emp_id,
del.emp_bankAccountNumber,
del.emp_salary,
del.emp_SSN
FROM deleted del
-- Audit NEW record.
INSERT INTO auditEmployeeData
(audit_log_type,
audit_emp_id,
audit_emp_bankAccountNumber,
audit_emp_salary,
audit_emp_SSN)
SELECT 'NEW',
ins.emp_id,
ins.emp_bankAccountNumber,
ins.emp_salary,
ins.emp_SSN
FROM inserted ins
END
GO
/*Inserting a new employee does not cause the UPDATE trigger to fire.*/
INSERT INTO employeeData
VALUES ( 101, 'USA-987-01', 23000, 'R-M53550M', N'Mendel', N'Roland', 32)
GO
/*Updating the employee record for employee number 101 to change the salary to 51000 causes the UPDATE trigger to fire and an audit trail to be produced.*/
UPDATE employeeData
SET emp_salary = 51000
WHERE emp_id = 101
GO
SELECT * FROM auditEmployeeData
GO
/*Updating the employee record for employee number 101 to change both the bank account number and social security number (SSN) causes the UPDATE trigger to fire and an audit trail to be produced.*/
UPDATE employeeData
SET emp_bankAccountNumber = '133146A0', emp_SSN = 'R-M53550M'
</code>   <code>WHERE emp_id = 101</code>
<code>GO</code>
<code>SELECT * FROM auditEmployeeData</code>
<code>GO</code>
</pre>
<h6>F. 使用 COLUMNS_UPDATED 测试 8 列以上</h6>
<p>如果必须测试影响到表中前 8 列以外的列的更新时，必须使用 UBSTRING 函数测试由 COLUMNS_UPDATED 返回的适当的位。下例测试影响 <strong>Northwind.dbo.Customers</strong> 表中的第 3、第 5 或第 9 列的更新。</p>
<pre><code>USE Northwind
DROP TRIGGER  tr1
GO
CREATE TRIGGER tr1 ON Customers
FOR UPDATE AS
IF ( (SUBSTRING(COLUMNS_UPDATED(),1,1)=power(2,(3-1))
+ power(2,(5-1)))
AND (SUBSTRING(COLUMNS_UPDATED(),2,1)=power(2,(1-1)))
)
PRINT 'Columns 3, 5 and 9 updated'
GO
UPDATE Customers
SET ContactName=ContactName,
Address=Address,
Country=Country
GO</code></pre>
</div>
<img src ="http://www.blogjava.net/xixidabao/aggbug/165947.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2007-12-07 09:13 <a href="http://www.blogjava.net/xixidabao/archive/2007/12/07/165947.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDBC连接数据库经验技巧</title><link>http://www.blogjava.net/xixidabao/archive/2007/10/12/152343.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Fri, 12 Oct 2007 06:36:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2007/10/12/152343.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 下面罗列了各种数据库使用JDBC连接的方式，可以作为一个手册使用。 　　1、Oracle8/8i/9i数据库（thin模式） 　　Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); 　　String url="jdbc:oracle:thin:@localhost:1521:orcl"; //orcl为...&nbsp;&nbsp;<a href='http://www.blogjava.net/xixidabao/archive/2007/10/12/152343.html'>阅读全文</a><img src ="http://www.blogjava.net/xixidabao/aggbug/152343.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2007-10-12 14:36 <a href="http://www.blogjava.net/xixidabao/archive/2007/10/12/152343.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate实践 </title><link>http://www.blogjava.net/xixidabao/archive/2007/08/29/140929.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Wed, 29 Aug 2007 07:18:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2007/08/29/140929.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 转:http://www.blogjava.net/BlueDavy/archive/2006/03/27/37582.html一. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 序 在实际项目中使用Hibernate有两年多了，在两年多的实践过程中既体验到了Hibernate带来的N多好处，同...&nbsp;&nbsp;<a href='http://www.blogjava.net/xixidabao/archive/2007/08/29/140929.html'>阅读全文</a><img src ="http://www.blogjava.net/xixidabao/aggbug/140929.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2007-08-29 15:18 <a href="http://www.blogjava.net/xixidabao/archive/2007/08/29/140929.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XXXX项目缓存方案总结</title><link>http://www.blogjava.net/xixidabao/archive/2007/08/28/140497.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Tue, 28 Aug 2007 06:35:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2007/08/28/140497.html</guid><description><![CDATA[<div>转:http://dev.csdn.net/author/bromon/8737868d27c74af7b4dbfc4d0497f4fa.html<br><br><br><br>XXXX项目缓存方案总结</div>
<div>&nbsp;</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XXXX</span>项目是目前在实际工作中正在做的事情，该项目是一个大型系统的内容管理内核，负责最核心的meta data的集中管理，性能有较高的要求，设计初期就要求能够支持cluster。项目使用hibernate 3.2，针对开发过程中对于各种缓存的不同看法，撰写了本文。重点在于澄清一些hibernate的缓存细节，纠正一些错误的缓存用法。</div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>一、</span>hibernate的二级缓存</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>如果开启了二级缓存，hibernate在执行任何一次查询的之后，都会把得到的结果集放到缓存中，缓存结构可以看作是一个hash table，key是数据库记录的id，value是id对应的pojo对象。当用户根据id查询对象的时候（load、iterator方法），会首先在缓存中查找，如果没有找到再发起数据库查询。但是如果使用hql发起查询（find, query方法）则不会利用二级缓存，而是直接从数据库获得数据，但是它会把得到的数据放到二级缓存备用。也就是说，基于hql的查询，对二级缓存是只写不读的。</div>
<div>&nbsp;</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>针对二级缓存的工作原理，采用iterator取代list来提高二级缓存命中率的想法是不可行的。Iterator的工作方式是根据检索条件从数据库中选取所有目标数据的id，然后用这些id一个一个的到二级缓存里面做检索，如果找到就直接加载，找不到就向数据库做查询。因此假如iterator检索100条数据的话，最好情况是100%全部命中，最坏情况是0%命中，执行101条sql把所有数据选出来。而list虽然不利用缓存，但是它只会发起1条sql取得所有数据。在合理利用分页查询的情况下，list整体效率高于iterator。</div>
<div>&nbsp;</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>二级缓存的失效机制由hibernate控制，当某条数据被修改之后，hibernate会根据它的id去做缓存失效操作。基于此机制，如果数据表不是被hibernate独占（比如同时使用jdbc或者ado等），那么二级缓存无法得到有效控制。</div>
<div>&nbsp;</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>由于hibernate的缓存接口很灵活，cache provider可以方便的切换，因此支持cluster环境不是大问题，通过使用swarmcache、jboss cache等支持分布式的缓存方案，可以实现。但是问题在于:</div>
<div style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt"><span>1、&nbsp;</span>分布式缓存本身成本偏高（比如使用同步复制模式的jboss cache）</div>
<div style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt"><span>2、&nbsp;</span>分布式环境通常对事务控制有较高要求，而目前的开源缓存方案对事务缓存（transaction cache）支持得不够好。当jta事务发生会滚，缓存的最后更新结果很难预料。这一点会带来很大的部署成本，甚至得不偿失。</div>
<div style="MARGIN-LEFT: 21pt">&nbsp;</div>
<div>结论：XXXX不应把hibernate二级缓存作为优化的主要手段，一般情况下建议不要使用。</div>
<div>&nbsp;</div>
<div>原因如下：</div>
<div style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt"><span>1、&nbsp;</span>XXXX的DAO类大部分是从1.0升级过来，由于1.0采用的是hibernate 2.1，所以在批量删除数据的时候采用了native sql的方式。虽然XXXX2.0已经完全升级到hibernate 3.2，支持hibernate原生的批量删改，但是由于hibernate批量操作的性能不如sql，而且为了兼容1.0的dao类，所以很多地方保留了sql操作。哪些数据表是单纯被hibernate独占无法统计，而且随着将来业务的发展可能会有很大变数。因此不宜采用二级缓存。</div>
<div style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt"><span>2、&nbsp;</span>针对系统业务来说，基于id检索的二级缓存命中率极为有限，hql被大量采用，二级缓存对性能的提升很有限。</div>
<div style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt"><span>3、&nbsp;</span>hibernate 3.0在做批量修改、批量更新的时候，是不会同步更新二级缓存的，该问题在hibernate 3.2中是否仍然存在尚不确定。</div>
<div style="MARGIN-LEFT: 21pt">&nbsp;</div>
<div>&nbsp;</div>
<div style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><span>二、</span>hibernate的查询缓存</div>
<div>&nbsp;</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>查询缓存的实现机制与二级缓存基本一致，最大的差异在于放入缓存中的key是查询的语句，value是查询之后得到的结果集的id列表。表面看来这样的方案似乎能解决hql利用缓存的问题，但是需要注意的是，构成key的是：hql生成的sql、sql的参数、排序、分页信息等。也就是说如果你的hql有小小的差异，比如第一条hql取1-50条数据，第二条hql取20-60条数据，那么hibernate会认为这是两个完全不同的key，无法重复利用缓存。因此利用率也不高。</div>
<div>&nbsp;</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>另外一个需要注意的问题是，查询缓存和二级缓存是有关联关系的，他们不是完全独立的两套东西。假如一个查询条件hql_1，第一次被执行的时候，它会从数据库取得数据，然后把查询条件作为key，把返回数据的所有id列表作为value（请注意仅仅是id）放到查询缓存中，同时整个结果集放到class缓存（也就是二级缓存），key是id，value是pojo对象。当你再次执行hql_1，它会从缓存中得到id列表，然后根据这些列表一个一个的到class缓存里面去找pojo对象，如果找不到就向数据库发起查询。也就是说，如果二级缓存配置了超时时间（或者发呆时间），就有可能出现查询缓存命中了，获得了id列表，但是class里面相应的pojo已经因为超时(或发呆)被失效，hibernate就会根据id清单，一个一个的去向数据库查询，有多少个id，就执行多少个sql。该情况将导致性能下降严重。</div>
<div>&nbsp;</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>查询缓存的失效机制也由hibernate控制，数据进入缓存时会有一个timestamp，它和数据表的timestamp对应。当hibernate环境内发生save、update等操作时，会更新被操作数据表的timestamp。用户在获取缓存的时候，一旦命中就会检查它的timestamp是否和数据表的timestamp匹配，如果不，缓存会被失效。因此查询缓存的失效控制是以数据表为粒度的，只要数据表中任何一条记录发生一点修改，整个表相关的所有查询缓存就都无效了。因此查询缓存的命中率可能会很低。</div>
<div>&nbsp;</div>
<div>结论：XXXX不应把hibernate二级缓存作为优化的主要手段，一般情况下建议不要使用。</div>
<div>&nbsp;</div>
<div>原因如下：</div>
<div style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt"><span>1、&nbsp;</span>XXXX的上层业务中检索条件都比较复杂，尤其是涉及多表操作的地方。很少出现重复执行一个排序、分页、参数一致的查询，因此命中率很难提高。</div>
<div style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt"><span>2、&nbsp;</span>查询缓存必须配合二级缓存一起使用，否则极易出现1+N的情况，否则性能不升反降</div>
<div style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt"><span>3、&nbsp;</span>使用查询缓存必须在执行查询之前显示调用Query.setCacheable(true)才能激活缓存，这势必会对已有的hibernate封装类带来问题。</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>总结</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>详细分析hibernate的二级缓存和查询缓存之后，针对XXXX项目的具体情况做出结论，在底层使用通用缓存方案的想法基本上是不可取的。比较好的做法是在高层次中（业务逻辑层面），针对具体的业务逻辑状况手动使用数据缓存，不仅可以完全控制缓存的生命周期，还可以针对业务具体调整缓存方案提交命中率。Cluster中的缓存同步可以完全交给缓存本身的同步机制来完成。比如开源缓存swarmcache采用invalidate的机制，可以根据用户指定的策略，在需要的时候向网络中的其他swarmcache节点发送失效消息，这一机制和XXXX1.0中已经采用的MappingCache的同步方案基本一致。建议采用。</div>
<img src ="http://www.blogjava.net/xixidabao/aggbug/140497.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2007-08-28 14:35 <a href="http://www.blogjava.net/xixidabao/archive/2007/08/28/140497.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何在oracle使用blob,clob</title><link>http://www.blogjava.net/xixidabao/archive/2007/08/22/138584.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Wed, 22 Aug 2007 05:05:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2007/08/22/138584.html</guid><description><![CDATA[<span id=Label4>转:http://blog.tostudy.com.cn/blog/show_930.html&nbsp;
<p><br>一.写入BLOB</p>
<p>1.先在blob中插入empty_blob()<br>2.获得对刚刚插入记录的引用<br>BLOB blob = (BLOB) rs.getBlob("你的blob字段名称");<br>3.写入<br>OutputStream out = blob.getBinaryOutputStream();<br>out.write(ENCYPWD);//注意这里<br>二.读出BLOB</p>
<p>1.blob&nbsp; = rs.getBlob("你的blob字段名称");<br>2.<br>InputStream is = blob.getBinaryStream();<br>int length = (int) blob.length();<br>byte[] buffer = new byte[length];<br>is.read(buffer);<br>is.close();<br>3.你有了is就随便处理了<br>比如说输出到一个文件<br>FileOutputStream fo = new FileOutputStream(filename);//数据到的文件名<br>fo.write(buffer);<br>fo.close();</p>
环境：<br>Database: Oracle 9i<br>App Server: BEA Weblogic 8.14<br></strong>表结构：<br>CREATE TABLE TESTBLOB (ID Int, NAME Varchar2(20), BLOBATTR Blob)<br>CREATE TABLE TESTBLOB (ID Int, NAME Varchar2(20), CLOBATTR Clob)</strong> &nbsp; JAVA可以通过JDBC，也可以通过JNDI访问并操作数据库，这两种方式的具体操作存在着一些差异，由于通过App Server的数据库连接池JNDI获得的数据库连接提供的java.sql.Blob和java.sql.Clob实现类与JDBC方式提供的不同，因此在入库操作的时候需要分别对待；出库操作没有这种差异，因此不用单独对待。 <br>一、BLOB操作<br>1、入库<br>（1）JDBC方式<br>&nbsp;&nbsp;&nbsp; //通过JDBC获得数据库连接<br>&nbsp;&nbsp;&nbsp; Class.forName("oracle.jdbc.driver.OracleDriver");<br>&nbsp;&nbsp;&nbsp; Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:testdb", "test", "test");<br>&nbsp;&nbsp;&nbsp; con.setAutoCommit(false);<br>&nbsp;&nbsp;&nbsp; Statement st = con.createStatement();<br>&nbsp;&nbsp;&nbsp; //插入一个空对象empty_blob()<br>&nbsp;&nbsp;&nbsp; st.executeUpdate("insert into TESTBLOB (ID, NAME, BLOBATTR) values (1, "thename", empty_blob())");<br>&nbsp;&nbsp;&nbsp; //锁定数据行进行更新，注意&#8220;for update&#8221;语句<br>&nbsp;&nbsp;&nbsp; ResultSet rs = st.executeQuery("select BLOBATTR from TESTBLOB where ID=1 for update");<br>&nbsp;&nbsp;&nbsp; if (rs.next())<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //得到java.sql.Blob对象后强制转换为oracle.sql.BLOB<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob("BLOBATTR");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OutputStream outStream = blob.getBinaryOutputStream();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //data是传入的byte数组，定义：byte[] data<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outStream.write(data, 0, data.length);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; outStream.flush();<br>&nbsp;&nbsp;&nbsp; outStream.close();<br>&nbsp;&nbsp;&nbsp; con.commit();<br>&nbsp;&nbsp;&nbsp; con.close();</strong> （2）JNDI方式<br>&nbsp;&nbsp;&nbsp; //通过JNDI获得数据库连接<br>&nbsp;&nbsp;&nbsp; Context context = new InitialContext();<br>&nbsp;&nbsp;&nbsp; ds = (DataSource) context.lookup("ORA_JNDI");<br>&nbsp;&nbsp;&nbsp; Connection con = ds.getConnection();<br>&nbsp;&nbsp;&nbsp; con.setAutoCommit(false);<br>&nbsp;&nbsp;&nbsp; Statement st = con.createStatement();<br>&nbsp;&nbsp;&nbsp; //插入一个空对象empty_blob()<br>&nbsp;&nbsp;&nbsp; st.executeUpdate("insert into TESTBLOB (ID, NAME, BLOBATTR) values (1, "thename", empty_blob())");<br>&nbsp;&nbsp;&nbsp; //锁定数据行进行更新，注意&#8220;for update&#8221;语句<br>&nbsp;&nbsp;&nbsp; ResultSet rs = st.executeQuery("select BLOBATTR from TESTBLOB where ID=1 for update");<br>&nbsp;&nbsp;&nbsp; if (rs.next())<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //得到java.sql.Blob对象后强制转换为weblogic.jdbc.vendor.oracle.OracleThinBlob（不同的App Server对应的可能会不同）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; weblogic.jdbc.vendor.oracle.OracleThinBlob blob = (weblogic.jdbc.vendor.oracle.OracleThinBlob) rs.getBlob("BLOBATTR");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OutputStream outStream = blob.getBinaryOutputStream();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //data是传入的byte数组，定义：byte[] data<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outStream.write(data, 0, data.length);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; outStream.flush();<br>&nbsp;&nbsp;&nbsp; outStream.close();<br>&nbsp;&nbsp;&nbsp; con.commit();<br>&nbsp;&nbsp;&nbsp; con.close();</strong> 2、出库<br>&nbsp;&nbsp;&nbsp; //获得数据库连接<br>&nbsp;&nbsp;&nbsp; Connection con = ConnectionFactory.getConnection();<br>&nbsp;&nbsp;&nbsp; con.setAutoCommit(false);<br>&nbsp;&nbsp;&nbsp; Statement st = con.createStatement();<br>&nbsp;&nbsp;&nbsp; //不需要&#8220;for update&#8221;<br>&nbsp;&nbsp;&nbsp; ResultSet rs = st.executeQuery("select BLOBATTR from TESTBLOB where ID=1");<br>&nbsp;&nbsp;&nbsp; if (rs.next())<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.sql.Blob blob = rs.getBlob("BLOBATTR");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputStream inStream = blob.getBinaryStream();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //data是读出并需要返回的数据，类型是byte[]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data = new byte[input.available()];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inStream.read(data);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inStream.close();<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; inStream.close();<br>&nbsp;&nbsp;&nbsp; con.commit();<br>&nbsp;&nbsp;&nbsp; con.close();</strong> &nbsp; 二、CLOB操作<br>1、入库<br>（1）JDBC方式<br>&nbsp;&nbsp;&nbsp; //通过JDBC获得数据库连接<br>&nbsp;&nbsp;&nbsp; Class.forName("oracle.jdbc.driver.OracleDriver");<br>&nbsp;&nbsp;&nbsp; Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:testdb", "test", "test");<br>&nbsp;&nbsp;&nbsp; con.setAutoCommit(false);<br>&nbsp;&nbsp;&nbsp; Statement st = con.createStatement();<br>&nbsp;&nbsp;&nbsp; //插入一个空对象empty_clob()<br>&nbsp;&nbsp;&nbsp; st.executeUpdate("insert into TESTCLOB (ID, NAME, CLOBATTR) values (1, "thename", empty_clob())");<br>&nbsp;&nbsp;&nbsp; //锁定数据行进行更新，注意&#8220;for update&#8221;语句<br>&nbsp;&nbsp;&nbsp; ResultSet rs = st.executeQuery("select CLOBATTR from TESTCLOB where ID=1 for update");<br>&nbsp;&nbsp;&nbsp; if (rs.next())<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //得到java.sql.Clob对象后强制转换为oracle.sql.CLOB<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oracle.sql.CLOB clob = (oracle.sql.CLOB) rs.getClob("CLOBATTR");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Writer outStream = clob.getCharacterOutputStream();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //data是传入的字符串，定义：String data<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] c = data.toCharArray();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outStream.write(c, 0, c.length);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; outStream.flush();<br>&nbsp;&nbsp;&nbsp; outStream.close();<br>&nbsp;&nbsp;&nbsp; con.commit();<br>&nbsp;&nbsp;&nbsp; con.close();<br></strong>（2）JNDI方式<br>&nbsp;&nbsp;&nbsp; //通过JNDI获得数据库连接<br>&nbsp;&nbsp;&nbsp; Context context = new InitialContext();<br>&nbsp;&nbsp;&nbsp; ds = (DataSource) context.lookup("ORA_JNDI");<br>&nbsp;&nbsp;&nbsp; Connection con = ds.getConnection();<br>&nbsp;&nbsp;&nbsp; con.setAutoCommit(false);<br>&nbsp;&nbsp;&nbsp; Statement st = con.createStatement();<br>&nbsp;&nbsp;&nbsp; //插入一个空对象empty_clob()<br>&nbsp;&nbsp;&nbsp; st.executeUpdate("insert into TESTCLOB (ID, NAME, CLOBATTR) values (1, "thename", empty_clob())");<br>&nbsp;&nbsp;&nbsp; //锁定数据行进行更新，注意&#8220;for update&#8221;语句<br>&nbsp;&nbsp;&nbsp; ResultSet rs = st.executeQuery("select CLOBATTR from TESTCLOB where ID=1 for update");<br>&nbsp;&nbsp;&nbsp; if (rs.next())<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //得到java.sql.Clob对象后强制转换为weblogic.jdbc.vendor.oracle.OracleThinClob（不同的App Server对应的可能会不同）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; weblogic.jdbc.vendor.oracle.OracleThinClob clob = (weblogic.jdbc.vendor.oracle.OracleThinClob) rs.getClob("CLOBATTR");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Writer outStream = clob.getCharacterOutputStream();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //data是传入的字符串，定义：String data<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] c = data.toCharArray();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outStream.write(c, 0, c.length);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; outStream.flush();<br>&nbsp;&nbsp;&nbsp; outStream.close();<br>&nbsp;&nbsp;&nbsp; con.commit();<br>&nbsp;&nbsp;&nbsp; con.close();</strong> 2、出库<br>&nbsp;&nbsp;&nbsp; //获得数据库连接<br>&nbsp;&nbsp;&nbsp; Connection con = ConnectionFactory.getConnection();<br>&nbsp;&nbsp;&nbsp; con.setAutoCommit(false);<br>&nbsp;&nbsp;&nbsp; Statement st = con.createStatement();<br>&nbsp;&nbsp;&nbsp; //不需要&#8220;for update&#8221;<br>&nbsp;&nbsp;&nbsp; ResultSet rs = st.executeQuery("select CLOBATTR from TESTCLOB where ID=1");<br>&nbsp;&nbsp;&nbsp; if (rs.next())<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.sql.Clob clob = rs.getClob("CLOBATTR");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Reader inStream = clob.getCharacterStream();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] c = new char[(int) clob.length()];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inStream.read(c);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //data是读出并需要返回的数据，类型是String<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data = new String(c);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inStream.close();<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; inStream.close();<br>&nbsp;&nbsp;&nbsp; con.commit();<br>&nbsp;&nbsp;&nbsp; con.close();</strong> &nbsp; 需要注意的地方：<br>1、java.sql.Blob、oracle.sql.BLOB、weblogic.jdbc.vendor.oracle.OracleThinBlob几种类型的区别<br>2、java.sql.Clob、oracle.sql.CLOB、weblogic.jdbc.vendor.oracle.OracleThinClob几种类型的区别</strong> </span>
<img src ="http://www.blogjava.net/xixidabao/aggbug/138584.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2007-08-22 13:05 <a href="http://www.blogjava.net/xixidabao/archive/2007/08/22/138584.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java实现的ftp文件上传例题 </title><link>http://www.blogjava.net/xixidabao/archive/2007/08/15/136861.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Wed, 15 Aug 2007 04:03:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2007/08/15/136861.html</guid><description><![CDATA[<font face=宋体 size=2><br>&nbsp;转:http://www.128kj.com/article/article5/4C981624F129B81E393E4DFE72AC9096.htm?id=1820<br><br><br>前几天写过一编"关于java的http协议文件上传实用例题"的文章；今天还想写编关于java用ftp上传文件的内容。我来说说2者的优缺点；<br>&nbsp;&nbsp;&nbsp; 1：用http协议上传更适合web编程的方便；传小于1M文件速度要比用ftp协议上传文件略快。安全性好；不像ftp那样；必须要启动一个ftp服务才行。<br><br>&nbsp;&nbsp;&nbsp; 2：用ftp协议上传文件大于1M的文件速度比http快；文件越大；上传的速度就比http上传快的倍数越大。而且用java编写程序；ftp比http方便。好，废话少说；我们先搭建一个实例来理性认识一下用java编写ftp上传文件的技术。</font>
<p><font face=宋体 size=2>&nbsp; 首先在本机启动一个ftp服务，ftp的用户："IUSR_ZJH" 密码："123"；随后在ftp主目录下建一个名为upftp的子目录；下面有4个文件就可启动这个例题了。</font></p>
<p><font face=宋体,sans-serif size=2>文件1：MainCtrl.java（servlet文件）内容如下：</font></p>
<p><font face=宋体,sans-serif>import javax.servlet.http.HttpServlet;<br>import javax.servlet.http.HttpServletRequest;<br>import javax.servlet.http.HttpServletResponse;<br>import javax.servlet.ServletException;</font></p>
<p><font face=宋体,sans-serif>import java.io.FileInputStream;<br>import java.io.IOException;</font></p>
<p><font face=宋体,sans-serif>import sun.net.TelnetOutputStream;<br>import sun.net.ftp.FtpClient;</font></p>
<p><br><font face=宋体,sans-serif>public class MainCtrl extends HttpServlet {<br>&nbsp;<br>&nbsp;&nbsp; private FtpClient ftpClient;<br>&nbsp;&nbsp; <br>&nbsp;public void doPost(HttpServletRequest req, HttpServletResponse resp) <br>&nbsp;throws ServletException, IOException {</font></p>
<p><font face=宋体,sans-serif>&nbsp;&nbsp; resp.setContentType("text/html; charset=UTF-8");</font></p>
<p><font face=宋体,sans-serif>&nbsp;&nbsp; try {<br>&nbsp;&nbsp;&nbsp; //连接ftp服务器<br>&nbsp;&nbsp;&nbsp; connectServer("127.0.0.1", "IUSR_ZJH", "123", "upftp");<br>&nbsp;&nbsp;//上传文件;并返回上传文件的信息<br>&nbsp;&nbsp;&nbsp; req.setAttribute("inf", upload(req.getParameter("file_name")));<br>&nbsp;&nbsp; } catch (Exception e) {<br>&nbsp;&nbsp;System.out.println(e.toString());<br>&nbsp;&nbsp;req.setAttribute("inf", e.toString());<br>&nbsp;&nbsp;req.getRequestDispatcher("view_inf.jsp").forward(req, resp);<br>&nbsp;&nbsp;return;<br>&nbsp;&nbsp; } finally {<br>&nbsp;&nbsp;&nbsp; if (ftpClient != null) {<br>&nbsp;&nbsp;&nbsp;&nbsp; ftpClient.closeServer();&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp; req.getRequestDispatcher("view_inf.jsp").forward(req, resp);<br>&nbsp; }<br>&nbsp; <br>&nbsp; public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {<br>&nbsp;&nbsp; doPost(req, resp);<br>&nbsp; }<br>//连接ftp服务器<br>&nbsp;private void connectServer(String server, String user, String password,<br>&nbsp;&nbsp;&nbsp;String path) throws IOException {<br>&nbsp;&nbsp;// server：FTP服务器的IP地址；user:登录FTP服务器的用户名<br>&nbsp;&nbsp;// password：登录FTP服务器的用户名的口令；path：FTP服务器上的路径<br>&nbsp;&nbsp;ftpClient = new FtpClient();<br>&nbsp;&nbsp;ftpClient.openServer(server);<br>&nbsp;&nbsp;ftpClient.login(user, password);<br>&nbsp;&nbsp;//path是ftp服务下主目录的子目录<br>&nbsp;&nbsp;if (path.length() != 0)<br>&nbsp;&nbsp;&nbsp;ftpClient.cd(path);<br>&nbsp;&nbsp;//用2进制上传<br>&nbsp;&nbsp;ftpClient.binary();<br>&nbsp;}</font></p>
<p><font face=宋体,sans-serif>&nbsp;//上传文件;并返回上传文件的信息<br>&nbsp;private String upload(String filename) throws Exception {<br>&nbsp;&nbsp;TelnetOutputStream os = null;<br>&nbsp;&nbsp;FileInputStream is = null;<br>&nbsp;&nbsp;try {<br>&nbsp;&nbsp;&nbsp;//"upftpfile"用ftp上传后的新文件名<br>&nbsp;&nbsp;&nbsp;os = ftpClient.put("upftpfile");<br>&nbsp;&nbsp;&nbsp;java.io.File file_in = new java.io.File(filename);<br>&nbsp;&nbsp;&nbsp;if (file_in.length()==0) {<br>&nbsp;&nbsp;&nbsp;&nbsp;return "上传文件为空!";<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;is = new FileInputStream(file_in);<br>&nbsp;&nbsp;&nbsp;byte[] bytes = new byte[1024];<br>&nbsp;&nbsp;&nbsp;int c;<br>&nbsp;&nbsp;&nbsp;while ((c = is.read(bytes)) != -1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;os.write(bytes, 0, c);<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;} finally {<br>&nbsp;&nbsp;&nbsp;if (is != null) {<br>&nbsp;&nbsp;&nbsp;&nbsp;is.close();<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;if (os != null) {<br>&nbsp;&nbsp;&nbsp;&nbsp;os.close();<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;return "上传文件成功!";<br>&nbsp;}</font></p>
<p><font face=宋体,sans-serif>}</font></p>
<p><font face=宋体,sans-serif size=2>文件2：upftp.htm(前台操作页面)内容如下：</font></p>
<p><font size=2><font face=宋体,sans-serif>&nbsp; </font><textarea style="WIDTH: 502px; HEIGHT: 145px" name=textarea rows=6 cols=60>&lt;html&gt;&lt;body&gt;
&lt;form method="post" action="/upftp/MainCtrl"&gt;
&lt;!-- C:\\Downloads\\setup_kubao.exe客户端真实文件路径 --&gt;
&lt;input type="text" name="file_name" size="38" value="C:\\Downloads\\setup_kubao.exe" /&gt;
&lt;input type="submit" /&gt;
&lt;/form&gt;&lt;/body&gt;
&lt;/html&gt;</textarea></font></p>
<p>文件3：view_inf.jsp(信息提示页面)和upftp.htm一样放在context的根目录下,</p>
<p>内容如下：</p>
<p>&lt;<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#37;&#64;&#112;&#97;&#103;&#101;"><u><font color=#0000ff>%@page</font></u></a> contentType="text/html;charset=UTF-8"%&gt;<br>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "<a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><u><font color=#0000ff>http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd</font></u></a>"&gt;<br>&lt;html xmlns="<a href="http://www.w3.org/1999/xhtml"><u><font color=#0000ff>http://www.w3.org/1999/xhtml</font></u></a>"&gt;<br>&lt;head&gt;<br>&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&gt;<br>&lt;style type="text/css"&gt;<br>th<br>{<br>background-color: #4455aa;<br>color: white;<br>font-size: 14px;<br>font-weight:bold;<br>}<br>td.TableBody1<br>{<br>background-color: #FFFFF0;<br>color: white;<br>font-size: 14px;<br>font-weight:bold;<br>font-color: red;<br>}<br>.tableBorder1<br>{<br>width:97%;<br>border: 1px; <br>background-color: #6595D6;<br>}<br>&lt;/style&gt;<br>&lt;/head&gt;<br>&lt;body&gt;<br>&lt;%String inf = (String) request.getAttribute("inf");<br>&nbsp;&nbsp; if (inf == null) {<br>&nbsp;&nbsp;&nbsp; inf = request.getParameter("inf");<br>&nbsp;&nbsp; }%&gt;<br>&lt;table class="tableborder1" style="width: 75%;" align="center"<br>&nbsp;cellpadding="3" cellspacing="1"&gt;<br>&nbsp;&lt;tbody&gt;<br>&nbsp; &lt;tr align="center"&gt;<br>&nbsp;&nbsp; &lt;th colspan="2" height="25" width="100%"&gt;信 息 提 示:&lt;/th&gt;<br>&nbsp; &lt;/tr&gt;<br>&nbsp; &lt;tr align="center"&gt;<br>&nbsp;&nbsp; &lt;td class="tablebody1" colspan="2" width="100%" height="200"&gt;&lt;%=inf%&gt;&lt;/td&gt;<br>&nbsp; &lt;/tr&gt;<br>&nbsp; &lt;tr align="center"&gt;<br>&nbsp;&nbsp; &lt;td&gt;&lt;input name="back" value="返 回" onclick="history.back();"<br>&nbsp;&nbsp;&nbsp; type="button" /&gt;&lt;/td&gt;<br>&nbsp; &lt;/tr&gt;<br>&nbsp;&lt;/tbody&gt;<br>&lt;/table&gt;<br>&lt;/body&gt;&lt;/html&gt;</p>
<p>文件4：web.xml(j2ee的备置文件)放在WEB-INF目录下,</p>
<p>内容如下：<br>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br>&lt;web-app xmlns="<a href="http://java.sun.com/xml/ns/j2ee"><u><font color=#0000ff>http://java.sun.com/xml/ns/j2ee</font></u></a>"<br>&nbsp;xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance"><u><font color=#0000ff>http://www.w3.org/2001/XMLSchema-instance</font></u></a>"<br>&nbsp;xsi:schemaLocation="<a href="http://java.sun.com/xml/ns/j2ee"><u><font color=#0000ff>http://java.sun.com/xml/ns/j2ee</font></u></a> <a href="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"><u><font color=#0000ff>http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd</font></u></a>"<br>&nbsp;version="2.4"&gt;<br>&nbsp;&lt;!--Servlet name--&gt;<br>&nbsp;&lt;servlet&gt;<br>&nbsp;&nbsp;&lt;servlet-name&gt;MainCtrl&lt;/servlet-name&gt;<br>&nbsp;&nbsp;&lt;servlet-class&gt;MainCtrl&lt;/servlet-class&gt;<br>&nbsp;&lt;/servlet&gt;<br>&nbsp;&lt;!--Servlet mapping--&gt;<br>&nbsp;&lt;servlet-mapping&gt;<br>&nbsp;&nbsp;&lt;servlet-name&gt;MainCtrl&lt;/servlet-name&gt;<br>&nbsp;&nbsp;&lt;url-pattern&gt;/MainCtrl&lt;/url-pattern&gt;<br>&nbsp;&lt;/servlet-mapping&gt;<br>&lt;/web-app&gt;</p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/xixidabao/aggbug/136861.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2007-08-15 12:03 <a href="http://www.blogjava.net/xixidabao/archive/2007/08/15/136861.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>有关乱码的处理</title><link>http://www.blogjava.net/xixidabao/archive/2007/08/14/136660.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Tue, 14 Aug 2007 06:08:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2007/08/14/136660.html</guid><description><![CDATA[来源：soddabao－BlogJava<br><br>　　为什么说乱码是中国程序员无法避免的话题呢？这个首先要从编码机制上说起，大家都是中文和英文的编码格式不是一样，解码也是不一样的！如果中国的程序员不会遇到乱码，那么只有使用汉语编程。汉语编程是怎么回事我也不大清楚，应该是前年吧，我一朋友给我介绍汉语编程，怎么不错不错？当时因为学习忙没去关注这个，等我闲了，那个朋友不弄这个，问他他也不说不大清楚，最后自己对这个学习也不了了之了。<br><br>今天我写这个不是讲解中英文之间的差距，解码等，我是将我在这几年工作遇到各种各样的乱码的解决方法，总结一样，也希望大家能把自己晕倒解决乱码的方法都说出来，咱们弄一个解决乱码的&#8220;葵花宝典&#8221;。<br><br>　　对于Java由于默认的编码方式是 UNICODE,所以用中文也易出问题,常见的解决是<br>String s2 = new String(s1.getBytes(&#8220;ISO-8859-1&#8221;),&#8221;GBK&#8221;); <br><br>　　1、utf8解决JSP中文乱码问题 <br><br>　　一般说来在每个页面的开始处，加入：<br><br>＜%@ page language="java" contentType="text/html; charset=UTF-8"<br>pageEncoding="UTF-8"%＞<br><br>＜%<br>request.setCharacterEncoding("UTF-8"); <br>%＞ <br><br>　　charset=UTF-8 的作用是指定JSP向客户端输出的编码方式为&#8220;UTF-8&#8221;<br><br>　　pageEncoding="UTF-8" 为了让JSP引擎能正确地解码含有中文字符的JSP页面，这在LINUX中很有效<br><br>　　request.setCharacterEncoding("UTF-8"); 是对请求进行了中文编码<br><br>　　有时，这样仍不能解决问题，还需要这样处理一下：<br><br>String msg = request.getParameter("message"); <br>String str=new String(msg.getBytes("ISO-8859-1"),"UTF-8"); <br>out.println(st); <br><br>　　2、Tomcat 5.5 中文乱码 <br><br>　　只要把%TOMCAT安装目录%/ webapps\servlets-examples\WEB-INF\classes\filters\SetCharacterEncodingFilter.class文件拷到你的webapp目录/filters下，如果没有filters目录，就创建一个。 <br><br>　 2)在你的web.xml里加入如下几行：<br><br>＜filter＞ <br>＜filter-name＞Set Character Encoding＜/filter-name＞ <br>＜filter-class＞filters.SetCharacterEncodingFilter＜/filter-class＞ <br>＜init-param＞ <br>＜param-name＞encoding＜/param-name＞ <br>＜param-value＞GBK＜/param-value＞ <br>＜/init-param＞ <br>＜/filter＞ <br>＜filter-mapping＞ <br>＜filter-name＞Set Character Encoding＜/filter-name＞ <br>＜url-pattern＞/*＜/url-pattern＞ <br>＜/filter-mapping＞ <br><br>　 3)完成.<br><br>　 2 get方式的解决办法 <br><br>　 1) 打开tomcat的server.xml文件，找到区块，加入如下一行： <br><br>URIEncoding=&#8221;GBK&#8221; <br><br>　 完整的应如下： <br>　<br>＜Connector <br>port="80" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" <br>enableLookups="false" redirectPort="8443" acceptCount="100" <br>debug="0" connectionTimeout="20000" <br>disableUploadTimeout="true" <br>URIEncoding="GBK" <br>/＞ <br><br>　2)重启tomcat,一切OK。<br><br>　　3、xmlHttpRequest中文问题 <br><br>　　页面jsp用的GBK编码 <br><br>＜%@ page contentType="text/html; charset=GBK"%＞ <br><br>　　javascript部分 <br><br>function addFracasReport() { <br>var url="controler?actionId=0_06_03_01&amp;actionFlag=0010"; <br>var urlmsg="&amp;reportId="+fracasReport1.textReportId.value; //故障报告表编号 <br><br>var xmlHttp=Common.createXMLHttpRequest(); <br>xmlHttp.onreadystatechange = Common.getReadyStateHandler(xmlHttp, eval("turnAnalyPage")); <br>xmlHttp.open("POST",url,true); <br>xmlHttp.setRequestHeader( " Content-Type " , " application/x-www-form-urlencoded); <br>xmlHttp.send(urlmsg); <br><br>} <br><br>　　后台java中获得的reportId是乱码，不知道该怎么转，主要是不知道xmlHttp.send(urlmsg); 以后是什么编码？在后面用java来转，试了几种，都没有成功，其中有：<br><br>public static String UTF_8ToGBK(String str) { <br>try { <br>return new String(str.getBytes("UTF-8"), "GBK"); <br>} catch (Exception ex) { <br>return null; <br>} <br>} <br><br>public static String UTF8ToGBK(String str) { <br>try { <br>return new String(str.getBytes("UTF-16BE"), "GBK"); <br>} catch (Exception ex) { <br>return null; <br>} <br>} <br><br>public static String GBK(String str) { <br>try { <br>return new String(str.getBytes("GBK"),"GBK"); <br>} catch (Exception ex) { <br>return null; <br>} <br>} <br>public static String getStr(String str) { <br>try { <br>String temp_p = str; <br>String temp = new String(temp_p.getBytes("ISO8859_1"), "GBK"); <br>temp = sqlStrchop(temp); <br>return temp; <br>} catch (Exception e) { <br>return null; <br>} <br>} <br><br>　　4、JDBC ODBC Bridge的Bug及其解决方法 <br><br>　　在编写一数据库管理程序时，发现JDBC-ODBC Bridge存在不易发现的Bug。在向数据表插入数据时，如果为英文字符，存储内容完全正确，如果存入中文字符，部分数据库只能存储前七八个中文字符，其他内容被截去，导致存储内容的不完整（有些数据库不存在这个问题，如Sybase SQL Anywhere 5.0。JDBC-ODBC Bridge还存在无法建表的Bug）。 <br><br>　　对于广大需要存储中文信息的Java程序员来说，这可是一个不好的消息。要么改用其他语言编程，要么选择其他价格昂贵的数据库产品。&#8220;一次编写，到处运行&#8221;的目标，也大打折扣。能不能采用变通的方法，将中文信息进行处理后再存储来解决这个问题呢？答案是肯定的。 <br><br>　　解决问题的具体思路、方法 <br><br>　　Java采用Unicode码编码方式，中英文字符均采用16bit存储。既然存储英文信息是正确的，根据一定规则，将中文信息转换成英文信息后存储，自然不会出现截尾现象。读取信息时再进行逆向操作，将英文信息还原成中文信息即可。由GB2312编码规则可知，汉字一般为二个高位为1的ASCII码，在转换时将一个汉字的二个高位1去掉，还原时再将二个高位1加上。为了处理含有英文字符的中文字串，对英文字符则需要加上一个Byte 0标记。以下提供的两个公用静态方法，可加入任何一个类中使用。 <br><br>　　将中英文字串转换成纯英文字串 <br><br>　　public static String toTureAsciiStr(String str){ <br><br>　　StringBuffer sb = new StringBuffer(); <br><br>　　byte[] bt = str.getBytes(); <br><br>　　for(int i =0 ; i〈bt.length; i++){ <br><br>　　if(bt[i]〈0){ <br><br>　　//是汉字去高位1 <br><br>　　sb.append((char)(bt[i]&amp;&amp;0x7f)); <br><br>　　 }else{//是英文字符 补0作记录 <br><br>　　sb.append((char)0); <br><br>　　sb.append((char)bt[i]); <br><br>　　 } <br><br>　　 } <br><br>　　return sb.toString(); <br><br>　　} <br><br>　　将经转换的字串还原 <br><br>　　public static String unToTrueAsciiStr(String str){ <br><br>　　 byte[] bt = str.getBytes(); <br><br>　　 int i,l=0,length = bt.length,j=0; <br><br>　　 for(i = 0; i〈length; i++){ <br><br>　　 if(bt[i] == 0){ <br><br>　　 l++; <br><br>　　 } <br><br>　　 } <br><br>　　 byte []bt2 = new byte[length-l]; <br><br>　　 for(i =0 ; i〈length; i++){ <br><br>　　 if(bt[i] == 0){ <br><br>　　 i++; <br><br>　　 bt2[j] = bt[i]; <br><br>　　 }else{ <br><br>　　 bt2[j] = (byte)(bt[i]|0x80); <br><br>　　 } <br><br>　　 j++; <br><br>　　 } <br><br>　　String tt = new String(bt2); <br><br>　　return tt; <br><br>　　} <br><br>　　上例在实际编程中效果很好，只是存储的中文信息需要经过同样处理，才能被其他系统使用。而且如果中文字串出现英文字符，实际上增加了额外的存储空间。<br><br>　　5、Solaris下Servlet编程的中文问题及解决办法 <br><br>　　在使用Java开发Internet上的一个应用系统时，发现在Windows下调试完全正常的Servlet，上传到Solaris 服务器上，运行却出现故障——返回的网页不能显示中文，应为中文的信息全为乱码；用中文信息做关键字，不能正确检索数据库。后来采用加入检查代码等方法探知故障原因如下： <br><br>　　显示乱码主要是因为通过类 HttpServletResponse提供的方法setContentType 无法改变返回给客户的数据的编码方式，正确的编码方式应为GB2312或者GBK，而事实上为缺省的ISO8859-1。无法检索中文信息则是因为，客户提交的中文信息经浏览器编码到达服务器后，Servlet无法将其正确解码。 <br><br>　　举例说明显示乱码解决方法 <br><br>　　Servlet 一般通常做法如下： <br><br>　　public class ZldTestServlet extends HttpServlet { <br><br>　　public void doGet (HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException{ <br><br>　　//在使用 Writer向浏览器返回数据前，设置 content-type header ，在这里设置相应的字符集gb2312 <br><br>　　response.setContentType("text/html; charset=gb2312"); <br><br>　　PrintWriter out = response.getWriter(); //* <br><br>　　// 正式返回数据 <br><br>　　out.println("〈html〉〈head〉〈title〉Servlet test〈/title〉〈/head〉" ); <br><br>　　out.println("这是一个测试页！"); <br><br>　　out.println("〈/body〉〈/html〉"); <br><br>　　out.close(); <br><br>　　} <br><br>　　 ... <br><br>　　} <br><br>　　解决页面显示乱码问题，需将*处代码换成如下内容： <br><br>　　PrintWriter out = new PrintWriter(new OutputStreamWriter(response.getOutputStream(),"gb2312")); <br><br>　　Solaris中文信息检索问题的解决 <br>　　浏览器利用表单向服务器提交信息时，一般采用x-www-form-urlencoded 的MIME格式对数据进行编码。如果使用get方法，参数名称和参数值经编码后附加在URL后，在Java中称作查询串（query string）。 <br><br>　　在Servlet程序中，如果采用ServletRequest的方法getParameter取得参数值，在Solaris环境下，对汉字却不能正确解码。因而无法正确检索数据库。 <br><br>　　在Java 1.2的包——java.net中提供了URLEncode和URLDecode类。类URLEncode提供了按x-www-form-urlencoded格式对给定串进行转换的方法。类URLEncode则提供了逆方法。 <br><br>　　6、Common Mail乱码问题<br><br>　　common mail是一个小而方便的mail包，他实现了对Java Mail的封装，使用起来十分的方便，但是我在使用他的时候发现，使用纯文本的内容发送，结果是乱码，代码如下：<br><br>public class TestCommonMail {<br>public static void main(String[] args) throws EmailException, MessagingException {<br>SimpleEmail email = new SimpleEmail(); <br>email.setCharset("GB2312"); <br>email.setHostName("smtp.163.com"); <br>email.setSubject("test"); <br>email.addTo("test@163.com"); <br>email.setFrom("test@163.com"); <br>email.setMsg("我的测试"); <br>email.setAuthentication("test", "test"); <br>email.send(); <br>}<br>}<br><br>分析了一下commons mail的源码找到了原因。源码如下:<br><br>public class SimpleEmail extends Email<br>{<br>public Email setMsg(String msg) throws EmailException, MessagingException<br>{<br>if (EmailUtils.isEmpty(msg))<br>{<br>throw new EmailException("Invalid message supplied"); <br>}<br><br>setContent(msg, TEXT_PLAIN); <br>return this; <br>}<br>}<br><br>Email代码片段<br><br>public void setContent(Object aObject, String aContentType)<br>{<br>this.content = aObject; <br>if (EmailUtils.isEmpty(aContentType))<br>{<br>this.contentType = null; <br>}<br>else<br>{<br>// set the content type<br>this.contentType = aContentType; <br><br>// set the charset if the input was properly formed<br>String strMarker = "; charset="; <br>int charsetPos = aContentType.toLowerCase().indexOf(strMarker); <br>if (charsetPos != -1)<br>{<br>// find the next space (after the marker)<br>charsetPos += strMarker.length(); <br>int intCharsetEnd =<br>aContentType.toLowerCase().indexOf(" ", charsetPos); <br><br>if (intCharsetEnd != -1)<br>{<br>this.charset =<br>aContentType.substring(charsetPos, intCharsetEnd); <br>}<br>else<br>{<br>this.charset = aContentType.substring(charsetPos); <br>}<br>}<br>}<br>}<br><br>email.send(); 的send方法将调用<br>public void buildMimeMessage() throws EmailException<br>{<br>try<br>{<br>this.getMailSession(); <br>this.message = new MimeMessage(this.session); <br><br>if (EmailUtils.isNotEmpty(this.subject))<br>{<br>if (EmailUtils.isNotEmpty(this.charset))<br>{<br>this.message.setSubject(this.subject, this.charset); <br>}<br>else<br>{<br>this.message.setSubject(this.subject); <br>}<br>}<br><br>// ========================================================<br>// Start of replacement code<br>if (this.content != null)<br>{<br>this.message.setContent(this.content, this.contentType); <br>}<br>// end of replacement code<br>// ========================================================<br>else if (this.emailBody != null)<br>{<br>this.message.setContent(this.emailBody); <br>}<br>else<br>{<br>this.message.setContent("", Email.TEXT_PLAIN); <br>}<br><br>if (this.fromAddress != null)<br>{<br>this.message.setFrom(this.fromAddress); <br>}<br>else<br>{<br>throw new EmailException("Sender address required"); <br>}<br><br>if (this.toList.size() + this.ccList.size() + this.bccList.size() == 0)<br>{<br>throw new EmailException(<br>"At least one receiver address required"); <br>}<br><br>if (this.toList.size() ＞ 0)<br>{<br>this.message.setRecipients(<br>Message.RecipientType.TO,<br>this.toInternetAddressArray(this.toList)); <br>}<br><br>if (this.ccList.size() ＞ 0)<br>{<br>this.message.setRecipients(<br>Message.RecipientType.CC,<br>this.toInternetAddressArray(this.ccList)); <br>}<br><br>if (this.bccList.size() ＞ 0)<br>{<br>this.message.setRecipients(<br>Message.RecipientType.BCC,<br>this.toInternetAddressArray(this.bccList)); <br>}<br><br>if (this.replyList.size() ＞ 0)<br>{<br>this.message.setReplyTo(<br>this.toInternetAddressArray(this.replyList)); <br>}<br><br>if (this.headers.size() ＞ 0)<br>{<br>Iterator iterHeaderKeys = this.headers.keySet().iterator(); <br>while (iterHeaderKeys.hasNext())<br>{<br>String name = (String) iterHeaderKeys.next(); <br>String value = (String) headers.get(name); <br>this.message.addHeader(name, value); <br>}<br>}<br><br>if (this.message.getSentDate() == null)<br>{<br>this.message.setSentDate(getSentDate()); <br>}<br><br>if (this.popBeforeSmtp)<br>{<br>Store store = session.getStore("pop3"); <br>store.connect(this.popHost, this.popUsername, this.popPassword); <br>}<br>}<br>catch (MessagingException me)<br>{<br>throw new EmailException(me); <br>}<br>}<br>由代码可以知道纯文本方式最终调用了Java Mail的<br>message.setContent(this.content, this.contentType); <br>content是内容<br>contentType是类型，如text/plain,<br>(我们可以试试直接用Java mail发邮件，设置文本内容不使用setText方法，也使用setContent("测试", "text/plain")方式，你可以看到内容也是乱码)<br><br>　　关键就在于text/plain，我们改成text/plain; charset=gb2312，ok乱码解决了。在commons mail我们看SimpleEmail 类中setMsg方法调用的就是 setContent(msg, TEXT_PLAIN); 我们只需要将Email类中的常量TEXT_PLAIN修改一下加入 charset=你的字符集 ，重新打包jar，这样就可以了<br><br>　　7、toad的字符集的设置与oracle的安装<br><br>　　oracle数据库服务器的安装一般是中文字符集，有时安装在不同的平台下，设置为ISO编码，toad是oracle开发的最好工具，不是我说的，可是中文环境下安装的toad，打开英文字符的oracle时，中文全是乱码。必须进行设置<br><br>环境变量---〉系统变量<br>加<br>NLS_lANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK<br>或<br>NLS_lANG=AMERICAN_AMERICA.WE8ISO8859P1<br><br>AMERICAN_AMERICA.WE8MSWIN1252<br><br>或者<br><br>打开注册表，点击HKEY_LOCAL_MATHINE<br>再点击Software,再点击ORACLE<br>在点击HOME（ORACLE所在目录）<br>在注册表的右半面有NLS_LANG,<br>双击它，将你想要的覆盖掉原来的就可以了<br>最好记下旧的，以便可以改回来。<br><br>connect sys/chang_on_install<br>update props$<br>set value$='ZHS16CGB231280'<br>where name='NLS_CHARACTERSET'; <br>commit; <br>这样就OK了<br><br>　　8、如何解決GWT(google web toolkit)中文的問題<br><br>　　GWT 中文乱码解决方法 <br><br>1.把你要显示的中文&#8220;测试字符串&#8221;输入到一个文件，如:1.txt <br>2.进入命令行,进入1.txt所在的目录,敲入以下命令:native2ascii.exe 1.txt 2.txt 回车。这样就生成了另外一个文件2.txt。 <br>3.2.txt的内容如下:\u6d4b\u8bd5\u5b57\u7b26\u4e32 <br>4.然后用上面的编码，在gwt中使用，就可以了. <br><br>　　9、xmlHttp得到的网页怎么是乱码？ <br><br>　　(1)在服务器端使用WebRequest而不是xmlHttp<br>　　(2) 将 <br><br>StreamReader sr = new StreamReader(stream); <br><br>　　对于简体中文改成：<br><br>StreamReader sr = new StreamReader(stream , Encoding.Default ); <br><br>　　对于utf-8改成：<br><br>StreamReader sr = new StreamReader(stream , Encoding.UTF8 ); <br><br>　　当然，Encoding枚举还有很多其他的成员，对于不同的编码content-type可以有选择的应用<br><br>　　(3)后来我发现无论是content-type是gb2312还是utf-8,用<br><br>StreamReader sr = new StreamReader(stream , Encoding.Default ); <br><br>　　都可以返回正常的汉字，所以统一的改成Encoding.Default<br><br><br><br><br>--------------------------------------------------------------------------------<br><br>最后，在服务器端从一个url获得网页的源代码的代码如下：<br><br><br><br>/// ＜summary＞<br>/// post一个指定的url，获得网页的源代码(用WebRequest实现)<br>/// ＜/summary＞<br>/// ＜param name="url"＞＜/param＞<br>/// ＜returns＞<br>/// 如果请求失败，返回null<br>/// 如果请求成功，返回网页的源代码<br>/// ＜/returns＞<br>public static string GetContentFromUrl2( string url )<br>{<br>//变量定义<br>string respstr; <br><br>WebRequest myWebRequest=WebRequest.Create(url); <br>// myWebRequest.PreAuthenticate=true; <br>// NetworkCredential networkCredential=new NetworkCredential( username , password , domain ); <br>// myWebRequest.Credentials=networkCredential; <br><br>// Assign the response object of 'WebRequest' to a 'WebResponse' variable.<br>WebResponse myWebResponse=myWebRequest.GetResponse(); <br>System.IO.Stream stream = myWebResponse.GetResponseStream(); <br>StreamReader sr = new StreamReader(stream , Encoding.Default ); <br>//以字符串形式读取数据流<br>respstr = sr.ReadToEnd(); <br>sr.Close(); <br><br>return respstr; <br><br>}
<img src ="http://www.blogjava.net/xixidabao/aggbug/136660.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2007-08-14 14:08 <a href="http://www.blogjava.net/xixidabao/archive/2007/08/14/136660.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>写得蛮好的linux学习笔记</title><link>http://www.blogjava.net/xixidabao/archive/2007/08/14/136537.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Mon, 13 Aug 2007 16:21:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2007/08/14/136537.html</guid><description><![CDATA[<div>
<div>
<div>linux<font face=宋体>目录架构</font><br>/ &nbsp; <font face=宋体>根目录</font><br>/bin&nbsp;&nbsp;&nbsp; <font face=宋体>常用的命令</font> binary file <font face=宋体>的目錄</font><br>/boot&nbsp;&nbsp; <font face=宋体>存放系统启动时必须读取的档案，包括核心</font> (kernel) <font face=宋体>在内</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /boot/grub/menu.lst&nbsp;&nbsp; GRUB<font face=宋体>设置</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /boot/vmlinuz&nbsp;&nbsp; <font face=宋体>内核</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /boot/initrd&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>核心解壓縮所需</font> RAM Disk<br>/dev&nbsp;&nbsp;&nbsp; <font face=宋体>系统周边设备</font>&nbsp;&nbsp;&nbsp;&nbsp; <br>/etc&nbsp;&nbsp;&nbsp; <font face=宋体>系统相关设定文件</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/DIR_COLORS&nbsp;&nbsp; <font face=宋体>设定颜色</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/HOSTNAME&nbsp;&nbsp; <font face=宋体>设定用户的节点名</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/NETWORKING&nbsp;&nbsp; <font face=宋体>只有</font>YES<font face=宋体>标明网络存在</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/host.conf <font face=宋体>文件说明用户的系统如何查询节点名</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/hosts <font face=宋体>设定用户自已的</font>IP<font face=宋体>与名字的对应表</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/hosts.allow <font face=宋体>设置允许使用</font>inetd<font face=宋体>的机器使用</font> <br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/hosts.deny <font face=宋体>设置不允许使用</font>inetd<font face=宋体>的机器使用</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/hosts.equiv <font face=宋体>设置远端机不用密码</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/inetd.conf <font face=宋体>设定系统网络守护进程</font>inetd<font face=宋体>的配置</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/gateways <font face=宋体>设定路由器</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/protocols <font face=宋体>设定系统支持的协议</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/named.boot <font face=宋体>设定本机为名字服务器的配置文件</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/sysconfig/network-scripts/ifcfg-eth0&nbsp;&nbsp; <font face=宋体>设置</font>IP<br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/resolv.conf&nbsp;&nbsp;&nbsp; <font face=宋体>设置</font>DNS&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/X11&nbsp; X Window<font face=宋体>的配置文件</font>,xorg.conf <font face=宋体>或</font> XF86Config <font face=宋体>這兩個</font> X Server <font face=宋体>的設定檔</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/fstab&nbsp;&nbsp;&nbsp; <font face=宋体>记录开机要</font>mount<font face=宋体>的文件系统</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/inittab <font face=宋体>设定系统启动时</font>init<font face=宋体>进程将把系统设置成什么样的</font>runlevel<br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/issue <font face=宋体>记录用户登录前显示的信息</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/group <font face=宋体>设定用户的组名与相关信息</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/passwd <font face=宋体>帐号信息</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/shadow <font face=宋体>密码信息</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/sudoers <font face=宋体>可以</font>sudo<font face=宋体>命令的配置文件</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/securetty <font face=宋体>设定哪些终端可以让</font>root<font face=宋体>登录</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/login.defs <font face=宋体>所有用户登录时的缺省配置</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/exports <font face=宋体>设定</font>NFS<font face=宋体>系统用的</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/init.d/&nbsp;&nbsp; <font face=宋体>所有服務的預設啟動</font> script <font face=宋体>都是放在這裡的，例如要啟動或者關閉</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/xinetd.d/&nbsp; <font face=宋体>這就是所謂的</font> super daemon <font face=宋体>管理的各項服務的設定檔目錄</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/modprobe.conf&nbsp;&nbsp; <font face=宋体>内核模块额外参数设定</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /etc/syslog.conf&nbsp;&nbsp; <font face=宋体>日志设置文件</font><br>/home&nbsp;&nbsp; <font face=宋体>使用者家目录</font><br>/lib&nbsp;&nbsp;&nbsp; <font face=宋体>系统会使用到的函数库</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /lib/modules&nbsp;&nbsp; kernel <font face=宋体>的相关模块</font><br>&nbsp;&nbsp;&nbsp;&nbsp; /var/lib/rpm&nbsp;&nbsp; rpm<font face=宋体>套件安装处</font> <br>/lost+found&nbsp;&nbsp;&nbsp; <font face=宋体>系統不正常產生錯誤時，會將一些遺失的片段放置於此目錄下</font><br>/mnt&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>外设的挂载点</font><br>/media&nbsp;&nbsp; <font face=宋体>与</font>/mnt<font face=宋体>类似</font><br>/opt&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>主机额外安装的软件</font><br>/proc&nbsp;&nbsp;&nbsp; <font face=宋体>虚拟目录，是内存的映射</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /proc/version&nbsp;&nbsp; <font face=宋体>内核版本</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /proc/sys/kernel&nbsp;&nbsp; <font face=宋体>系统内核功能</font><br>/root&nbsp;&nbsp;&nbsp; <font face=宋体>系统管理员的家目录</font><br>/sbin&nbsp;&nbsp;&nbsp; <font face=宋体>系统管理员才能执行的指令</font><br>/srv&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>一些服務啟動之後，這些服務所需要取用的資料目錄</font><br>/tmp&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>一般使用者或者是正在執行的程序暫時放置檔案的地方</font><br>/usr&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>最大的目录，存许应用程序和文件</font><br>&nbsp;&nbsp;&nbsp; /usr/X11R6<font face=宋体>：</font>&nbsp;&nbsp; X-Window<font face=宋体>目录</font> <br>&nbsp;&nbsp;&nbsp; /usr/src<font face=宋体>：</font>&nbsp;&nbsp;&nbsp; Linux<font face=宋体>源代码</font><br>&nbsp;&nbsp;&nbsp; /usr/include<font face=宋体>：系统头文件</font><br>&nbsp;&nbsp;&nbsp; /usr/openwin <font face=宋体>存放</font>SUN<font face=宋体>的</font>OpenWin <br>&nbsp;&nbsp;&nbsp; /usr/man <font face=宋体>在线使用手册</font><br>&nbsp;&nbsp;&nbsp; /usr/bin&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>使用者可執行的</font> binary file <font face=宋体>的目錄</font><br>&nbsp;&nbsp;&nbsp; /usr/local/bin&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>使用者可執行的</font> binary file <font face=宋体>的目錄</font><br>&nbsp;&nbsp;&nbsp; /usr/lib&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>系统会使用到的函数库</font><br>&nbsp;&nbsp;&nbsp; /usr/local/lib&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>系统会使用到的函数库</font><br>&nbsp;&nbsp;&nbsp; /usr/sbin&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>系统管理员才能执行的指令</font><br>&nbsp;&nbsp;&nbsp; /usr/local/sbin&nbsp;&nbsp;&nbsp; <font face=宋体>系统管理员才能执行的指令</font><br>/var&nbsp;&nbsp; <font face=宋体>日志文件</font><br>&nbsp;&nbsp;&nbsp; /var/log/secure&nbsp;&nbsp;&nbsp; <font face=宋体>記錄登入系統存取資料的檔案，例如</font> pop3, ssh, telnet, ftp <font face=宋体>等都會記錄在此檔案中</font><br>&nbsp;&nbsp;&nbsp; /var/log/wtmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>記錄登入者的訊息資料</font>, last<br>&nbsp;&nbsp;&nbsp; /var/log/messages&nbsp; <font face=宋体>幾乎系統發生的錯誤訊息</font><br>&nbsp;&nbsp;&nbsp; /var/log/boot.log&nbsp; <font face=宋体>記錄開機或者是一些服務啟動的時候，所顯示的啟動或關閉訊息</font><br>&nbsp;&nbsp;&nbsp; /var/log/maillog&nbsp;&nbsp; <font face=宋体>紀錄郵件存取或往來</font>( sendmail <font face=宋体>與</font> pop3 )<font face=宋体>的使用者記錄</font><br>&nbsp;&nbsp;&nbsp; /var/log/cron&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>記錄</font> crontab <font face=宋体>這個例行性服務的內容</font><br>&nbsp;&nbsp;&nbsp; /var/log/httpd, /var/log/news, /var/log/mysqld.log, /var/log/samba, /var/log/procmail.log<font face=宋体>：</font><br>&nbsp;&nbsp;&nbsp; <font face=宋体>分別是幾個不同的網路服務的記錄檔</font></div>
<div>&nbsp;</div>
<div><font face=宋体>一些常用的基本命令</font>:<br>uname -a&nbsp;&nbsp;&nbsp; <font face=宋体>查看内核版本</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>ls -al&nbsp;&nbsp;&nbsp; <font face=宋体>显示所有文件的属性</font><br>pwd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示当前路径</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>cd -&nbsp;&nbsp;&nbsp; <font face=宋体>返回上一次目录</font>&nbsp;&nbsp;&nbsp;&nbsp; cd ~&nbsp;&nbsp;&nbsp; <font face=宋体>返回主目录</font><br>date s&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>设置时间、日期</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>cal&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示日历</font>&nbsp;&nbsp;&nbsp;&nbsp; cal 2006<br>bc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>计算器具</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>man&nbsp; &amp; info&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>帮助手册</font><br>locale&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示当前字体</font>&nbsp;&nbsp;&nbsp;&nbsp; locale -a&nbsp;&nbsp;&nbsp; <font face=宋体>所有可用字体</font>&nbsp;&nbsp;&nbsp;&nbsp; /etc/sysconfig/i18n<font face=宋体>设置文件</font><br>LANG=en&nbsp;&nbsp;&nbsp; <font face=宋体>使用英文字体</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>sync&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>将数据同步写入硬盘</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>shutdonw -h now &amp; half &amp; poweroff&nbsp; <font face=宋体>关机</font><br>reboot&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>重启</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>startx&nbsp; &amp;&nbsp; init 5&nbsp;&nbsp; <font face=宋体>进入图形介面</font><br>/work&nbsp; &amp; ?work&nbsp;&nbsp;&nbsp; <font face=宋体>向上、下查找文档内容</font><br>chgrp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>改变档案群组</font>&nbsp; chgrp testing install.log&nbsp;&nbsp;&nbsp; <br>chown&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>改变所属人</font>&nbsp;&nbsp; chown root:root install.log<br>chmod&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>改变属性</font>&nbsp;&nbsp;&nbsp;&nbsp; chmod 777 install.log&nbsp;&nbsp;&nbsp;&nbsp; read=4&nbsp; write=2&nbsp; execute=1<br>cp&nbsp;&nbsp; <font face=宋体>复制</font>&nbsp;&nbsp; cp filename<br>rm&nbsp;&nbsp; <font face=宋体>删除文件</font>&nbsp; rm -rf filename&nbsp;&nbsp; <font face=宋体>强制删除文件</font><br>rmdir&nbsp;&nbsp; <font face=宋体>删除文件夹</font><br>mv&nbsp; <font face=宋体>移动</font>&nbsp;&nbsp;&nbsp; mv 123.txt 222.txt&nbsp; <font face=宋体>重命名</font><br>mkdir&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>创建文件夹</font><br>touch&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>创建文件</font>&nbsp; <font face=宋体>更新当前时间</font><br>cat&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>由第一行开始显示</font>&nbsp;&nbsp;&nbsp;&nbsp; cat |more&nbsp; <font face=宋体>分页</font><br>nl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>在内容前加行号</font><br>more&nbsp; &amp;&nbsp; less&nbsp;&nbsp; <font face=宋体>一面一面翻动</font><br>head -n filename&nbsp;&nbsp; <font face=宋体>显示第</font>N<font face=宋体>行内容</font><br>tail -n filename&nbsp; <font face=宋体>显示后</font>N<font face=宋体>行内容</font><br>od&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示非纯文档</font><br>df -h <font face=宋体>显示分区空间</font><br>du&nbsp; <font face=宋体>显示目录或文件的大小</font><br>fdisk&nbsp;&nbsp; <font face=宋体>分区设置</font>&nbsp;&nbsp;&nbsp; fdisk -l /dev/hda&nbsp; <font face=宋体>显示硬盘分区状态</font><br>mkfs&nbsp;&nbsp;&nbsp; <font face=宋体>建立各种文件系统</font>&nbsp; mkfs -t ext3&nbsp; /dev/ram15&nbsp;&nbsp; <br>fsck&nbsp;&nbsp;&nbsp; <font face=宋体>检查和修复</font>LINUX<font face=宋体>档案</font><br>ln&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>硬链接</font>&nbsp;&nbsp; ln -s&nbsp; <font face=宋体>软件链接</font><br>whereis&nbsp;&nbsp; <font face=宋体>查找命令</font><br>locate&nbsp;&nbsp;&nbsp; <font face=宋体>查找</font><br>find&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>查找</font>&nbsp;&nbsp; find / -name "***.***"<br>which&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>查看工具</font><br>whoami&nbsp;&nbsp;&nbsp; <font face=宋体>显示当前用户</font><br>gcc -v&nbsp;&nbsp;&nbsp; <font face=宋体>查看</font>GCC<font face=宋体>版本</font><br>chattr +i filename&nbsp; <font face=宋体>禁止删除</font>&nbsp;&nbsp; chattr -i filename&nbsp; <font face=宋体>取消禁止</font><br>lsattr&nbsp;&nbsp;&nbsp; <font face=宋体>显示隐藏档属性</font><br>updatedb&nbsp; <font face=宋体>更新资料库</font><br>mke2fs&nbsp;&nbsp;&nbsp; <font face=宋体>格式化</font>&nbsp;&nbsp; mkfs -t ext3 <br>dd if=/etc/passwd of=/tmp/passwd.bak&nbsp;&nbsp;&nbsp; <font face=宋体>备份</font><br>mount&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>列出系统所有的分区</font><br>mount -t iso9660 /dev/cdrom /mnt/cdrom&nbsp;&nbsp; <font face=宋体>挂载光盘</font><br>mount -t vfat /dev/fd0 /mnt/floppy&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>挂载软盘</font><br>mount -t vfat -o iocharset=utf8,umask=000 /dev/hda2 /mnt/hda2&nbsp;&nbsp; <font face=宋体>挂载</font>fat32<font face=宋体>分区</font><br>mount -t ntfs -o nls=utf8,umask=000 /dev/hda3 /mnt/hda3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>挂载</font>ntfs<font face=宋体>分区</font><br>Linux-NTFS Project: <a href="http://linux-ntfs.sourceforge.net/"><font color=#223355><u>http://linux-ntfs.sourceforge.net/</u></font></a><br>umount /mnt/hda3&nbsp; <font face=宋体>缷载</font><br>ifconfig&nbsp;&nbsp; <font face=宋体>显示或设置网络设备</font><br>service network restart&nbsp;&nbsp; <font face=宋体>重启网卡</font>&nbsp; <br>ifdown eth0&nbsp; <font face=宋体>关闭网卡</font><br>ifup eth0&nbsp;&nbsp;&nbsp; <font face=宋体>开启网卡</font><br>clear&nbsp;&nbsp;&nbsp; <font face=宋体>清屏</font><br>history&nbsp;&nbsp;&nbsp; <font face=宋体>历史记录</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !55&nbsp; <font face=宋体>执行第</font>55<font face=宋体>个指令</font><br>stty&nbsp;&nbsp; <font face=宋体>设置终端</font>&nbsp;&nbsp;&nbsp; stty -a<br>fdisk /mbr&nbsp;&nbsp; <font face=宋体>删除</font>GRUB<br>at&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>僅進行一次的工作排程</font><br>crontab&nbsp;&nbsp; <font face=宋体>循環執行的例行性命令</font>&nbsp;&nbsp;&nbsp; [e]<font face=宋体>编辑</font>,[l]<font face=宋体>显示</font>,[r]<font face=宋体>删除任务</font><br>&amp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>后台运行程序</font>&nbsp;&nbsp;&nbsp; tar -zxvf 123.tar.gz &amp; ---------&gt;<font face=宋体>后台运行</font><br>jobs&nbsp;&nbsp;&nbsp; <font face=宋体>观看后台暂停的程序</font>&nbsp;&nbsp; jobs -l<br>fg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>将后台程序调到前台</font>&nbsp;&nbsp; fg n ------&gt;n<font face=宋体>是数字</font>,<font face=宋体>可以指定进行那个程序</font><br>bg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>让工作在后台运行</font><br>kill&nbsp;&nbsp;&nbsp; <font face=宋体>结束进程</font>&nbsp;&nbsp;&nbsp; kill -9 PID&nbsp;&nbsp;&nbsp;&nbsp; [9]<font face=宋体>强制结束</font>,[15]<font face=宋体>正常结束</font>,[l]<font face=宋体>列出可用的</font>kill<font face=宋体>信号</font><br>ps aux&nbsp; <font face=宋体>查看后台程序</font>&nbsp;&nbsp; <br>top&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>查看后台程序</font>&nbsp;&nbsp; top -d 2&nbsp;&nbsp;&nbsp; <font face=宋体>每两秒更新一次</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; top -d 2 -p10604&nbsp;&nbsp; <font face=宋体>观看某个</font>PID<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; top -b -n 2 &gt; /tmp/top.txt -----&gt;<font face=宋体>將</font> top <font face=宋体>的資訊進行</font> 2 <font face=宋体>次，然後將結果輸出到</font> /tmp/top.txt&nbsp;&nbsp;&nbsp; <br>pstree&nbsp;&nbsp; <font face=宋体>以树状图显示程序</font>&nbsp;&nbsp;&nbsp; [A]<font face=宋体>以</font> ASCII <font face=宋体>來連接</font>, [u]<font face=宋体>列出</font>PID, [p]<font face=宋体>列出帐号</font><br>killall&nbsp;&nbsp; <font face=宋体>要刪除某個服務</font>&nbsp;&nbsp;&nbsp; killall -9 httpd<br>free&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示内存状态</font>&nbsp;&nbsp;&nbsp;&nbsp; free -m&nbsp; --------&gt;<font face=宋体>以</font>M<font face=宋体>为单位显示</font><br>uptime&nbsp;&nbsp;&nbsp; <font face=宋体>显示目前系统开机时间</font><br>netstat&nbsp;&nbsp; <font face=宋体>显示网络状态</font>&nbsp;&nbsp;&nbsp; netstat -tulnp------&gt;<font face=宋体>找出目前系統上已在監聽的網路連線及其</font> PID<br>dmesg&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示开机信息</font>&nbsp;&nbsp;&nbsp; demsg | more<br>nice&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>设置优先权</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nice -n -5 vi &amp; -----&gt;<font face=宋体>用</font> root <font face=宋体>給一個</font> nice <font face=宋体>植為</font> -5 <font face=宋体>，用於執行</font> vi <br>renice&nbsp;&nbsp;&nbsp; <font face=宋体>调整已存在优先权</font><br>runlevel&nbsp; <font face=宋体>显示目前的</font>runlevel<br>depmod&nbsp;&nbsp;&nbsp; <font face=宋体>分析可载入模块的相依性</font><br>lsmod&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示已载入系统的模块</font><br>modinfo&nbsp;&nbsp; <font face=宋体>显示</font>kernel<font face=宋体>模块的信息</font><br>insmod&nbsp;&nbsp;&nbsp; <font face=宋体>载入模块</font><br>modprobe&nbsp;&nbsp; <font face=宋体>自动处理可载入模块</font><br>rmmod&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>删除模块</font><br>chkconfig&nbsp;&nbsp; <font face=宋体>检查，设置系统的各种服务</font>&nbsp;&nbsp;&nbsp;&nbsp; chkconfig --list -----&gt;<font face=宋体>列出各项服务状态</font><br>ntsysv&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>设置系统的各种服务</font><br>cpio&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>备份文件</font><br>&nbsp;</div>
<div><br><font face=宋体>压缩命令：</font><br>&nbsp;*.Z&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; compress <font face=宋体>程式壓縮的檔案；</font> <br>&nbsp;*.bz2&nbsp;&nbsp;&nbsp; bzip2 <font face=宋体>程式壓縮的檔案；</font> <br>&nbsp;*.gz&nbsp;&nbsp;&nbsp;&nbsp; gzip <font face=宋体>程式壓縮的檔案；</font> <br>&nbsp;*.tar&nbsp;&nbsp;&nbsp; tar <font face=宋体>程式打包的資料，並沒有壓縮過；</font> <br>&nbsp;*.tar.gz tar <font face=宋体>程式打包的檔案，其中並且經過</font> gzip <font face=宋体>的壓縮</font><br>compress filename&nbsp; <font face=宋体>压缩文件</font>&nbsp; <font face=宋体>加</font>[-d]<font face=宋体>解压</font>&nbsp; uncompress<br>gzip filename&nbsp;&nbsp; <font face=宋体>压缩</font>&nbsp; <font face=宋体>加</font>[-d]<font face=宋体>解压</font>&nbsp; zcat 123.gz <font face=宋体>查看压缩文件内容</font><br>bzip2 -z filename&nbsp; <font face=宋体>压缩</font>&nbsp; <font face=宋体>加</font>[-d]<font face=宋体>解压</font>&nbsp;&nbsp; bzcat filename.bz2&nbsp; <font face=宋体>查看压缩文件内容</font><br>tar -cvf /home/123.tar /etc&nbsp; <font face=宋体>打包，不压缩</font><br>tar -xvf 123.tar&nbsp;&nbsp; <font face=宋体>解开包</font><br>tar -zxvf /home/123.tar.gz&nbsp; <font face=宋体>以</font>gzip<font face=宋体>解压</font><br>tar -jxvf /home/123.tar.bz2&nbsp; <font face=宋体>以</font>bzip2<font face=宋体>解压</font><br>tar -ztvf /tmp/etc.tar.gz&nbsp;&nbsp; <font face=宋体>查看</font>tar<font face=宋体>内容</font><br>cpio -covB&nbsp; &gt; [file|device]&nbsp;&nbsp; <font face=宋体>份份</font><br>cpio -icduv &lt; [file|device]&nbsp;&nbsp; <font face=宋体>还原</font></div>
<div>&nbsp;</div>
<div>vi<font face=宋体>一般用法</font><br><font face=宋体>一般模式</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>编辑模式</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>指令模式</font><br>h <font face=宋体>左</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a,i,r,o,A,I,R,O&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :w <font face=宋体>保存</font><br>j <font face=宋体>下</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>进入编辑模式</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :w! <font face=宋体>强制保存</font><br>k <font face=宋体>上</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dd <font face=宋体>删除光标当前行</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :q! <font face=宋体>不保存离开</font><br>l <font face=宋体>右</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ndd <font face=宋体>删除</font>n<font face=宋体>行</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :wq! <font face=宋体>保存后离开</font><br>0 <font face=宋体>移动到行首</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; yy <font face=宋体>复制当前行</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :e! <font face=宋体>还原原始档</font><br>$ <font face=宋体>移动到行尾</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nyy <font face=宋体>复制</font>n<font face=宋体>行</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :w filename <font face=宋体>另存为</font><br>H <font face=宋体>屏幕最上</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p,P <font face=宋体>粘贴</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :set nu <font face=宋体>设置行号</font><br>M <font face=宋体>屏幕中央</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u&nbsp; <font face=宋体>撤消</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :set nonu <font face=宋体>取消行号</font><br>L <font face=宋体>屏幕最下</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Ctrl]+r <font face=宋体>重做上一个动作</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ZZ <font face=宋体>保存离开</font><br>G <font face=宋体>档案最后一行</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ctrl]+z <font face=宋体>暂停退出</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :set nohlsearch&nbsp;&nbsp; <font face=宋体>永久地关闭高亮显示</font><br>/work <font face=宋体>向下搜索</font>&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; :sp <font face=宋体>同时打开两个文档</font> <br>?work <font face=宋体>向上搜索</font>&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; [Ctrl]+w <font face=宋体>两个文档设换</font><br>gg <font face=宋体>移动到档案第一行</font>&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; :nohlsearch&nbsp;&nbsp;&nbsp; <font face=宋体>暂时关闭高亮显示</font></div>
<div>&nbsp;</div>
<div><font face=宋体>认识</font>SHELL<br>alias&nbsp;&nbsp;&nbsp; <font face=宋体>显示当前所有的命令别名</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alias lm="ls -al"&nbsp;&nbsp; <font face=宋体>命令别名</font>&nbsp;&nbsp;&nbsp; unalias lm <font face=宋体>取消命令别名</font><br>type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>类似</font>which<br>exprot&nbsp;&nbsp;&nbsp; <font face=宋体>设置或显示环境变量</font><br>exprot PATH="$PATH":/sbin&nbsp; <font face=宋体>添加</font>/sbin<font face=宋体>入</font>PATH<font face=宋体>路径</font><br>echo $PATH&nbsp;&nbsp;&nbsp; <font face=宋体>显示</font>PATH<font face=宋体>路径</font><br>bash&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>进入子程序</font><br>name=yang&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>设定变量</font><br>unset name&nbsp;&nbsp;&nbsp; <font face=宋体>取消变量</font><br>echo $name&nbsp;&nbsp;&nbsp; <font face=宋体>显示变量的内容</font><br>myname="$name its me"&nbsp;&nbsp; &amp;&nbsp;&nbsp; myname='$name its me'&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>单引号时</font>$name<font face=宋体>失去变量内容</font><br>ciw=/etc/sysconfig/network-scripts/&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>设置路径</font><br>env&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>列出所有环境变量</font><br>echo $RANDOM&nbsp;&nbsp;&nbsp; <font face=宋体>显示随意产生的数</font><br>set&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>设置</font>SHELL<br>PS1='[\u@\h \w \A #\#]\$ '&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>提示字元的設定</font><br>&nbsp;&nbsp; [root@linux ~]# read [-pt] variable&nbsp;&nbsp;&nbsp;&nbsp; -----------<font face=宋体>读取键盘输入的变量</font><br>&nbsp;&nbsp; <font face=宋体>參數：</font><br>&nbsp;&nbsp; -p&nbsp; <font face=宋体>：後面可以接提示字元！</font><br>&nbsp;&nbsp; -t&nbsp; <font face=宋体>：後面可以接等待的『秒數！』</font><br>declare&nbsp;&nbsp;&nbsp; <font face=宋体>声明</font> shell <font face=宋体>变量</font><br>ulimit -a&nbsp;&nbsp; <font face=宋体>显示所有限制资料</font><br>&nbsp;ls /tmp/yang &amp;&amp; echo "exist" || echo "not exist"<br>&nbsp;<font face=宋体>意思是說，當</font> ls /tmp/yang <font face=宋体>執行後，若正確，就執行</font>echo "exist" ,<font face=宋体>若有問題，就執行</font>echo "not exist" <br>&nbsp;echo $PATH | cut -d ':' -f 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>以</font>:<font face=宋体>为分隔符</font>,<font face=宋体>读取第</font>5<font face=宋体>段内容</font><br>&nbsp;export | cut -c 10-20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>读取第</font>10<font face=宋体>到</font>20<font face=宋体>个字节的内容</font><br>&nbsp;last | grep 'root'&nbsp;&nbsp;&nbsp; <font face=宋体>搜索有</font>root<font face=宋体>的一行</font>,<font face=宋体>加</font>[-v]<font face=宋体>反向搜索</font><br>&nbsp;cat /etc/passwd | sort&nbsp;&nbsp;&nbsp; <font face=宋体>排序显示</font><br>&nbsp;cat /etc/passwd | wc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示『行、字数、字节数』</font></div>
<div><font face=宋体>正规表示法</font><br>[root@test root]# grep [-acinv] '<font face=宋体>搜尋字串</font>' filename<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>參數說明：</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -a <font face=宋体>：將</font> binary <font face=宋体>檔案以</font> text <font face=宋体>檔案的方式搜尋資料</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -c <font face=宋体>：計算找到</font> '<font face=宋体>搜尋字串</font>' <font face=宋体>的次數</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -i <font face=宋体>：忽略大小寫的不同，所以大小寫視為相同</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -n <font face=宋体>：順便輸出行號</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -v <font face=宋体>：反向選擇，亦即顯示出沒有</font> '<font face=宋体>搜尋字串</font>' <font face=宋体>內容的那一行！</font><br>&nbsp;grep -n 'the' 123.txt&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>搜索</font>the<font face=宋体>字符</font> -----------<font face=宋体>搜尋特定字串</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;grep -n 't[ea]st' 123.txt&nbsp;&nbsp;&nbsp; <font face=宋体>搜索</font>test<font face=宋体>或</font>taste<font face=宋体>两个字符</font>---------<font face=宋体>利用</font> [] <font face=宋体>來搜尋集合字元</font><br>&nbsp;grep -n '[^g]oo' 123.txt&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>搜索前面不为</font>g<font face=宋体>的</font>oo-----------<font face=宋体>向選擇</font> [^] <br>&nbsp;grep -n '[0-9]' 123.txt&nbsp; <font face=宋体>搜索有</font>0-9<font face=宋体>的数字</font><br>&nbsp;grep -n '^the' 123.txt <font face=宋体>搜索以</font>the<font face=宋体>为行首</font>-----------<font face=宋体>行首搜索</font>^<br>&nbsp;grep -n '^[^a-zA-Z]' 123.txt&nbsp; <font face=宋体>搜索不以英文字母开头</font><br>&nbsp;grep -n '[a-z]$' 123.txt&nbsp;&nbsp;&nbsp; <font face=宋体>搜索以</font>a-z<font face=宋体>结尾的行</font>---------- <font face=宋体>行尾搜索</font>$<br>&nbsp;grep -n 'g..d' 123.txt&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>搜索开头</font>g<font face=宋体>结尾</font>d<font face=宋体>字符</font>----------<font face=宋体>任意一個字元</font> . <br>&nbsp;grep -n 'ooo*' 123.txt&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>搜索至少有两个</font>oo<font face=宋体>的字符</font>---------<font face=宋体>重複字元</font> *<br>sed&nbsp;&nbsp;&nbsp; <font face=宋体>文本流编辑器</font>&nbsp;&nbsp;&nbsp; <font face=宋体>利用脚本命令来处理文本文件</font><br>awd&nbsp;&nbsp;&nbsp; <font face=宋体>模式扫描和处理语言</font><br>&nbsp;nl 123.txt | sed '2,5d'&nbsp;&nbsp; <font face=宋体>删除第二到第五行的内容</font><br>diff&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>比较文件的差异</font><br>cmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>比较两个文件是否有差异</font><br>patch&nbsp;&nbsp;&nbsp; <font face=宋体>修补文件</font><br>pr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>要打印的文件格式化</font><br>&nbsp;</div>
<div><br><font face=宋体>帐号管理</font><br>/etc/passwd&nbsp;&nbsp;&nbsp; <font face=宋体>系统帐号信息</font><br>/etc/shadow&nbsp;&nbsp;&nbsp; <font face=宋体>帐号密码信息</font>&nbsp;&nbsp;&nbsp; <font face=宋体>经</font>MD5 32<font face=宋体>位加密</font><br>&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>在密码栏前面加『</font> * <font face=宋体>』『</font> ! <font face=宋体>』禁止使用某帐号</font><br>/etc/group&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>系统群组信息</font><br>/etc/gshadow<br>newgrp&nbsp;&nbsp;&nbsp; <font face=宋体>改变登陆组</font><br>useradd&nbsp; &amp;&nbsp; adduser&nbsp;&nbsp;&nbsp; <font face=宋体>建立新用户</font>&nbsp; ---------&gt; useradd -m test&nbsp; <font face=宋体>自动建立用户的登入目录</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; useradd -m -g pgroup test ---------&gt;<font face=宋体>指定所属级</font><br>/etc/default/useradd&nbsp;&nbsp; <font face=宋体>相关设定</font><br>/etc/login.defs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UID/GID <font face=宋体>有關的設定</font><br>passwd&nbsp;&nbsp;&nbsp; <font face=宋体>更改密码</font> -----------&gt; passwd test<br>usermod&nbsp;&nbsp; <font face=宋体>修改用户帐号</font><br>userdel&nbsp;&nbsp; <font face=宋体>删除帐号</font> -----------&gt;userdel -r test<br>chsh&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>更换登陆系统时使用的</font>SHELL&nbsp;&nbsp; [-l]<font face=宋体>显示可用的</font>SHELL;[-s]<font face=宋体>修改自己的</font>SHELL<br>chfn&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>改变</font>finger<font face=宋体>指令显示的信息</font><br>finger&nbsp;&nbsp;&nbsp; <font face=宋体>查找并显示用户信息</font><br>id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示用户的</font>ID -----------&gt;&nbsp; id test<br>groupadd&nbsp;&nbsp; <font face=宋体>添加组</font><br>groupmod&nbsp;&nbsp; <font face=宋体>与</font>usermod<font face=宋体>类似</font><br>groupdel&nbsp;&nbsp; <font face=宋体>删除组</font><br>su test&nbsp;&nbsp;&nbsp; <font face=宋体>更改用户</font>&nbsp;&nbsp; su -&nbsp;&nbsp;&nbsp; <font face=宋体>进入</font>root,<font face=宋体>且使用</font>root<font face=宋体>的环境变量</font><br>sudo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>以其他身份来执行指令</font><br>visudo&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>编辑</font>/etc/sudoers&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>加入一行『</font> test ALL=(ALL) ALL <font face=宋体>』</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %wheel ALL = (ALL) ALL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>系统里所有</font>wheel<font face=宋体>群组的用户都可用</font>sudo<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %wheel ALL = (ALL) NOPASSWD: ALL&nbsp;&nbsp;&nbsp;&nbsp; wheel<font face=宋体>群组所有用户都不用密码</font>NOPASSWD<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; User_Alias ADMPW = vbird, dmtsai, vbird1, vbird3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>加入</font>ADMPW<font face=宋体>组</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ADMPW ALL = NOPASSWD: !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !/usr/bin/passwd root&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>可以更改使用者密码</font>,<font face=宋体>但不能更改</font>root<font face=宋体>密码</font> (<font face=宋体>在指令前面加入</font> ! <font face=宋体>代表不可</font>)<br>PAM (Pluggable Authentication Modules, <font face=宋体>嵌入式模組</font>)<br>who &amp; w&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>看谁在线</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>last&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>最近登陆主机的信息</font><br>lastlog&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>最近登入的時間</font>&nbsp;&nbsp;&nbsp; <font face=宋体>读取</font> /var/log/lastlog <br>talk&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>与其他用户交谈</font><br>write&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>发送信息</font>&nbsp;&nbsp;&nbsp; write test&nbsp;&nbsp; [ctrl]+d <font face=宋体>发送</font><br>mesg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>设置终端机的写入权限</font>&nbsp;&nbsp;&nbsp; mesg n <font face=宋体>禁止接收</font>&nbsp;&nbsp;&nbsp;&nbsp; mesg y <br>wall&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>向所有用户发送信息</font>&nbsp;&nbsp;&nbsp; wall this is q test<br>mail&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>写</font>mail&nbsp;&nbsp; <br>/etc/default/useradd&nbsp;&nbsp;&nbsp; <font face=宋体>家目录默认设置</font></div>
<div>quota&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>显示磁盘已使用的空间与限制</font>&nbsp;&nbsp;&nbsp;&nbsp; quota -guvs -----&gt;<font face=宋体>秀出目前</font> root <font face=宋体>自己的</font> quota <font face=宋体>限制值</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; quota -vu&nbsp;&nbsp; <font face=宋体>查询</font><br>quotacheck&nbsp;&nbsp; <font face=宋体>检查磁盘的使用空间与限制</font>&nbsp;&nbsp;&nbsp;&nbsp; quotacheck -avug&nbsp; -----&gt;<font face=宋体>將所有的在</font> /etc/mtab <font face=宋体>內，含有</font> quota <font face=宋体>支援的</font> partition <font face=宋体>進行掃瞄</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [-m] <font face=宋体>强制扫描</font>&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; quota<font face=宋体>一定要是独立的分区</font>,<font face=宋体>要有</font>quota.user<font face=宋体>和</font>quota.group<font face=宋体>两件文件</font>,<font face=宋体>在</font>/etc/fstab<font face=宋体>添加一句</font>:<br>&nbsp;&nbsp;&nbsp;&nbsp; /dev/hda3 /home ext3 defaults,usrquota,grpquota 1 2<br>&nbsp;&nbsp;&nbsp;&nbsp; chmod 600 quota*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>设置完成</font>,<font face=宋体>重启生效</font><br>edquota&nbsp;&nbsp;&nbsp; <font face=宋体>编辑用户或群组的</font>quota&nbsp; [u]<font face=宋体>用户</font>,[g]<font face=宋体>群组</font>,[p]<font face=宋体>复制</font>,[t]<font face=宋体>设置宽限期限</font> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edquota -a yang&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edquota -p yang -u young -----&gt;<font face=宋体>复制</font>&nbsp;&nbsp;&nbsp; <br>quotaon&nbsp;&nbsp;&nbsp; <font face=宋体>开启磁盘空间限制</font>&nbsp;&nbsp;&nbsp;&nbsp; quotaon -auvg --------&gt;<font face=宋体>啟動所有的具有</font> quota <font face=宋体>的</font> filesystem<br>quotaoff&nbsp;&nbsp; <font face=宋体>关闭磁盘空间限制</font>&nbsp;&nbsp;&nbsp;&nbsp; quotaoff -a&nbsp; --------&gt;<font face=宋体>關閉了</font> quota <font face=宋体>的限制</font><br>repquota -av&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>查閱系統內所有的具有</font> quota <font face=宋体>的</font> filesystem <font face=宋体>的限值狀態</font></div>
<div>Quota <font face=宋体>從開始準備</font> filesystem <font face=宋体>的支援到整個設定結束的主要的步驟大概是：</font><br>1<font face=宋体>、設定</font> partition <font face=宋体>的</font> filesystem <font face=宋体>支援</font> quota <font face=宋体>參數：</font><br><font face=宋体>由於</font> quota <font face=宋体>必須要讓</font> partition <font face=宋体>上面的</font> filesystem <font face=宋体>支援才行，一般來說，</font> <font face=宋体>支援度最好的是</font> ext2/ext3 <font face=宋体>，</font><br><font face=宋体>其他的</font> filesystem <font face=宋体>類型鳥哥我是沒有試過啦！</font> <font face=宋体>啟動</font> filesystem <font face=宋体>支援</font> quota <font face=宋体>最簡單就是編輯</font> /etc/fstab <font face=宋体>，</font><br><font face=宋体>使得準備要開放的</font> quota <font face=宋体>磁碟可以支援</font> quota <font face=宋体>囉；</font><br>2<font face=宋体>、建立</font> quota <font face=宋体>記錄檔：</font><br><font face=宋体>剛剛前面講過，整個</font> quota <font face=宋体>進行磁碟限制值記錄的檔案是</font> aquota.user/aquota.group<font face=宋体>，</font> <br><font face=宋体>要建立這兩個檔案就必須要先利用</font> quotacheck <font face=宋体>掃瞄才行喔！</font><br>3<font face=宋体>、編輯</font> quota <font face=宋体>限制值資料：</font><br><font face=宋体>再來就是使用</font> edquota <font face=宋体>來編輯每個使用者或群組的可使用空間囉；</font><br>4<font face=宋体>、重新掃瞄與啟動</font> quota <font face=宋体>：</font><br><font face=宋体>設定好</font> quota <font face=宋体>之後，建議可以再進行一次</font> quotacheck <font face=宋体>，然後再以</font> quotaon <font face=宋体>來啟動吧！</font></div>
<div><br><font face=宋体>开机流程简介</font><br>1<font face=宋体>、載入</font> BIOS <font face=宋体>的硬體資訊，並取得第一個開機裝置的代號；</font> <br>2<font face=宋体>、讀取第一個開機裝置的</font> MBR <font face=宋体>的</font> boot Loader (<font face=宋体>亦即是</font> lilo, grub, spfdisk <font face=宋体>等等</font>) <font face=宋体>的開機資訊；</font> <br>3<font face=宋体>、載入</font> Kernel <font face=宋体>作業系統核心資訊，</font> Kernel <font face=宋体>開始解壓縮，並且嘗試驅動所有硬體裝置；</font> <br>4<font face=宋体>、</font>Kernel <font face=宋体>執行</font> init <font face=宋体>程式並取得</font> run-level <font face=宋体>資訊；</font> <br>5<font face=宋体>、</font>init <font face=宋体>執行</font> /etc/rc.d/rc.sysinit <font face=宋体>檔案；</font> <br>6<font face=宋体>、啟動核心的外掛模組</font> (/etc/modprobe.conf)<font face=宋体>；</font> <br>7<font face=宋体>、</font>init <font face=宋体>執行</font> run-level <font face=宋体>的各個批次檔</font>( Scripts )<font face=宋体>；</font> <br>8<font face=宋体>、</font>init <font face=宋体>執行</font> /etc/rc.d/rc.local <font face=宋体>檔案；</font> <br>9<font face=宋体>、執行</font> /bin/login <font face=宋体>程式，並等待使用者登入；</font> <br>10<font face=宋体>、登入之後開始以</font> Shell <font face=宋体>控管主機。</font> </div>
<div><font face=宋体>在</font>/etc/rc.d/rc3.d<font face=宋体>內</font>,<font face=宋体>以</font>S<font face=宋体>开头的为开机启动</font>,<font face=宋体>以</font>K<font face=宋体>开头的为关闭</font>,<font face=宋体>接着的数字代表执行顺序</font></div>
<div>GRUB vga<font face=宋体>设定</font><br><font face=宋体>彩度</font>\<font face=宋体>解析度</font>&nbsp; 640x480&nbsp; 800x600&nbsp; 1024x768&nbsp; 1280x1024&nbsp;&nbsp; bit <br>&nbsp;&nbsp;&nbsp; 256&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 769&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 771&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 773&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 775&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8 bit <br>&nbsp;&nbsp; 32768&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 784&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 787&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 790&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 793&nbsp;&nbsp;&nbsp;&nbsp; 15 bit <br>&nbsp;&nbsp; 65536&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 785&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 788&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 791&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 794&nbsp;&nbsp;&nbsp;&nbsp; 16 bit <br>&nbsp;&nbsp; 16.8M&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 786&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 789&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 792&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 795&nbsp;&nbsp;&nbsp;&nbsp; 32 bit </div>
<div><br>./configure&nbsp;&nbsp;&nbsp; <font face=宋体>检查系统信息</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ./configure --help | more&nbsp; <font face=宋体>帮助信息</font><br>make clean&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>清除之前留下的文件</font><br>make&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=宋体>编译</font><br>make install&nbsp;&nbsp; <font face=宋体>安装</font></div>
<div>rpm -q&nbsp; -----&gt;<font face=宋体>查询是否安装</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rpm -ql ------&gt;<font face=宋体>查询该套件所有的目录</font><br>rpm -qi -----&gt;<font face=宋体>查询套件的说明资料</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rpm -qc[d] -----&gt;<font face=宋体>设定档与说明档</font><br>rpm -ivh&nbsp; ----&gt;<font face=宋体>安装</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rpm -V&nbsp; --------&gt;<font face=宋体>查看套件有否更动过</font><br>rpm -e&nbsp; ------&gt;<font face=宋体>删除</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rpm -Uvh -------&gt;<font face=宋体>升级安装</font>&nbsp; <br>--nodeps -----&gt;<font face=宋体>强行安装</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --test -----&gt;<font face=宋体>测试安装</font></div>
</div>
<div><font size=3><font face="Times New Roman"></font></font>转&nbsp;<a href="http://blog.chinaunix.net/u/30619/showart.php?id=249558">http://blog.chinaunix.net/u/30619/showart.php?id=249558</a></div>
<div></div>
</div>
<img src ="http://www.blogjava.net/xixidabao/aggbug/136537.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2007-08-14 00:21 <a href="http://www.blogjava.net/xixidabao/archive/2007/08/14/136537.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java实现随机验证码功能实例</title><link>http://www.blogjava.net/xixidabao/archive/2007/08/09/135382.html</link><dc:creator>JAVA之路</dc:creator><author>JAVA之路</author><pubDate>Wed, 08 Aug 2007 16:07:00 GMT</pubDate><guid>http://www.blogjava.net/xixidabao/archive/2007/08/09/135382.html</guid><description><![CDATA[<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="FONT-SIZE: 24pt; COLOR: #ff0000"> Java实现随机验证码功能实例<br></span><span>&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;&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2007-08-08 来自：lizhe1985&nbsp;&nbsp;</span><br><br><br>现在许多系统的注册、登录或者发布信息模块都添加的随机码功能，就是为了避免自动注册程序或者自动发布程序的使用。 <br><br>验证码实际上就是随机选择一些字符以图片的形式展现在页面上，如果进行提交操作的同时需要将图片上的字符同时提交，如果提交的字符与服务器session保存的不同，则认为提交信息无效。为了避免自动程序分析解析图片，通常会在图片上随机生成一些干扰线或者将字符进行扭曲，增加自动识别的难度。 <br><br>在这里，我们使用servlet来实现随机验证码的实现。 <br><br>package com.servlet; <br><br>import java.awt.Color; <br>import java.awt.Font; <br>import java.awt.Graphics2D; <br>import java.awt.image.BufferedImage; <br>import java.util.Random; <br><br>import javax.imageio.ImageIO; <br>import javax.servlet.ServletException; <br>import javax.servlet.ServletOutputStream; <br>import javax.servlet.http.HttpServlet; <br>import javax.servlet.http.HttpServletRequest; <br>import javax.servlet.http.HttpServletResponse; <br>import javax.servlet.http.HttpSession; <br><br>/**<br>* 生成随机验证码<br>* @author bitiliu<br>*<br>*/<br>public class ValidateCodeServlet extends HttpServlet <br>{<br><br>private static final long serialVersionUID = 1L; <br><br>//验证码图片的宽度。<br>private int width=60; <br>//验证码图片的高度。<br>private int height=20; <br>//验证码字符个数<br>private int codeCount=4; <br><br><br>private int x=0; <br>//字体高度<br>private int fontHeight; <br>private int codeY; <br><br>char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',<br>'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',<br>'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; <br><br>/**<br>* 初始化验证图片属性<br>*/<br>public void init() throws ServletException<br>{<br>//从web.xml中获取初始信息<br>//宽度<br>String strWidth=this.getInitParameter("width"); <br>//高度<br>String strHeight=this.getInitParameter("height"); <br>//字符个数<br>String strCodeCount=this.getInitParameter("codeCount"); <br><br>//将配置的信息转换成数值<br>try<br>{<br>if(strWidth!=null &amp;&amp; strWidth.length()!=0)<br>{<br>width=Integer.parseInt(strWidth); <br>}<br>if(strHeight!=null &amp;&amp; strHeight.length()!=0)<br>{<br>height=Integer.parseInt(strHeight); <br>}<br>if(strCodeCount!=null &amp;&amp; strCodeCount.length()!=0)<br>{<br>codeCount=Integer.parseInt(strCodeCount); <br>}<br>}<br>catch(NumberFormatException e)<br>{}<br><br>x=width/(codeCount+1); <br>fontHeight=height-2; <br>codeY=height-4; <br><br>}<br><br>protected void service(HttpServletRequest req, HttpServletResponse resp)<br>throws ServletException, java.io.IOException {<br><br>//定义图像buffer<br>BufferedImage buffImg = new BufferedImage(<br>width, height,BufferedImage.TYPE_INT_RGB); <br>Graphics2D g = buffImg.createGraphics(); <br><br>//创建一个随机数生成器类<br>Random random = new Random(); <br><br>//将图像填充为白色<br>g.setColor(Color.WHITE); <br>g.fillRect(0, 0, width, height); <br><br>//创建字体，字体的大小应该根据图片的高度来定。<br>Font font = new Font("Fixedsys", Font.PLAIN, fontHeight); <br>//设置字体。<br>g.setFont(font); <br><br>//画边框。<br>g.setColor(Color.BLACK); <br>g.drawRect(0, 0, width - 1, height - 1); <br><br>//随机产生160条干扰线，使图象中的认证码不易被其它程序探测到。<br>g.setColor(Color.BLACK); <br>for(int i = 0; i ＜ 160; i++) <br>{<br>int x = random.nextInt(width); <br>int y = random.nextInt(height); <br>int xl = random.nextInt(12); <br>int yl = random.nextInt(12); <br>g.drawLine(x, y, x + xl, y + yl); <br>}<br><br>//randomCode用于保存随机产生的验证码，以便用户登录后进行验证。<br>StringBuffer randomCode = new StringBuffer(); <br>int red = 0, green = 0, blue = 0; <br><br>//随机产生codeCount数字的验证码。<br>for (int i = 0; i ＜ codeCount; i++) {<br>//得到随机产生的验证码数字。<br>String strRand = String.valueOf(codeSequence[random.nextInt(36)]); <br>//产生随机的颜色分量来构造颜色值，这样输出的每位数字的颜色值都将不同。<br>red = random.nextInt(255); <br>green = random.nextInt(255); <br>blue = random.nextInt(255); <br><br>//用随机产生的颜色将验证码绘制到图像中。<br>g.setColor(new Color(red, green, blue)); <br>g.drawString(strRand, (i + 1) * x, codeY); <br><br>//将产生的四个随机数组合在一起。<br>randomCode.append(strRand); <br>}<br>// 将四位数字的验证码保存到Session中。<br>HttpSession session = req.getSession(); <br>session.setAttribute("validateCode", randomCode.toString()); <br><br>// 禁止图像缓存。<br>resp.setHeader("Pragma", "no-cache"); <br>resp.setHeader("Cache-Control", "no-cache"); <br>resp.setDateHeader("Expires", 0); <br><br>resp.setContentType("image/jpeg"); <br><br>//将图像输出到Servlet输出流中。<br>ServletOutputStream sos = resp.getOutputStream(); <br>ImageIO.write(buffImg, "jpeg", sos); <br>sos.close(); <br>}<br><br>} <br><br>需要在web.xml中声明servlet <br><br>＜servlet＞ <br>＜servlet-name＞ValidateCodeServlet＜/servlet-name＞ <br>＜servlet-class＞com.servlet.ValidateCodeServlet＜/servlet-class＞ <br>＜init-param＞ <br>＜param-name＞width＜/param-name＞ <br>＜param-value＞200＜/param-value＞ <br>＜/init-param＞ <br>＜init-param＞ <br>＜param-name＞height＜/param-name＞ <br>＜param-value＞80＜/param-value＞ <br>＜/init-param＞ <br>＜init-param＞ <br>＜param-name＞codeCount＜/param-name＞ <br>＜param-value＞5＜/param-value＞ <br>＜/init-param＞ <br>＜/servlet＞ <br><br>＜servlet-mapping＞ <br>＜servlet-name＞ValidateCodeServlet＜/servlet-name＞ <br>＜url-pattern＞/validateCodeServlet＜/url-pattern＞ <br>＜/servlet-mapping＞ <br><br>用户提交后就可以将用户输入的验证码与session中保存的字符串进行比对，达到验证的效果 
<img src ="http://www.blogjava.net/xixidabao/aggbug/135382.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xixidabao/" target="_blank">JAVA之路</a> 2007-08-09 00:07 <a href="http://www.blogjava.net/xixidabao/archive/2007/08/09/135382.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>