让System.out.println回家种田

原创 2004年04月29日 21:02:00

让System.out.println回家种田,换句话说,就是该干嘛干嘛去。

您可能在想: System.out.println几乎在每个Java程序里都有那么几行,如何让他老人家回家种田呢? 我们怎么能少了这么重要的革命同志呢?

doodoofish这里要说的是"该干嘛干嘛去",不是System.out.println管的就别让他管。想想,我们用System.out.println (文中称SOP,不是Service Oriented Programming,是System.out.println) 主要在三种情况下:

一、输出文本到stdout,作为输出结果;

二、显示调试信息,用来Debug;

三、显示信息,让管理员观赏

第一种情况,没得说,是SOP的老本行,不服不行。让他就继续干吧。

第二、三种情况,就不该SOP管,让他管也管不好。如果我调试用SOP来显示信息,一旦哪天我决定不要显示这些烦人的东西了,怎么办? 好办啊,一个文件一个文件找,一行一行找,把SOP给Comment起来不就完了,多方便啊。可是哪天我又要显示这些调试信息了,又怎么办? 第二天我又不要了,下个月我又要了... ... 我们程序员闲得慌吗? 可有人就是认为我们很闲,你的老板可能就是一个。我的朋友5bug是个天才,他说有办法,就是每个SOP前加一个 if 来判断是否显示。天才啊!

我比较笨,比郭靖还笨。我就没想到这个法子,一直没想出来,直到上10个星期,看到一篇介绍Log4J的文章。一开始看不懂 (我比较笨) ,倒过来看一遍总算懂了。

说起来又是一个类库,在http://logging.apache.org/site/binindex.cgi这里下载。然后就把那个log4j1.2.8.jar从"dist/lib"目录下copy到我的项目LogTest的"lib"目录下 (真烦,copy文件是很烦人的操作,需要一定的技术)。然后,我就写了个简单的class (复杂的我不会写) 来调用log4j的东东。

import

org.apache.log4j.*;

public

class LogTest {

    static Logger logger = Logger.getLogger(LogTest.class.getName());

    public static void main(String[] args) {

        logger.debug("Debug ...");

        logger.info("Info ...");

        logger.warn("Warn ...");

        logger.error("Error ...");

    }

}

没什么新鲜,就是个Logger。那"static Logger logger = Logger.getLogger(LogTest.class.getName());" 就是创建一个属於LogTest类的Logger对象,创建时要告知Logger你当前的Class是什么,所以就有了"LogTest.class.getName()"这奇怪的东东。

logger.debug就是输出debug的信息

logger.info就是输出提示信息

logger.warn就是显示警告信息

logger.error就是显示错误信息

log是什么? Log是个很深奥的古希腊名词,不贬义,也不褒义。说简单了,就是"日志",就是你要写什么就写什么,要写哪里就是哪里。不同与SOP,log4j可以让你把要写的东西分成4级 (其实有更多级,你可以自己定义,比如叫: 三级++),这些级别叫优先权 (Priority),这里四个优先权就是debug, info, warn, 和error,优先权从低到高,log4j能让你控制显示哪些优先权的信息。log4j也让你要写哪就哪,可以是屏幕,可以是一个文件,甚至是一个Email,一个XML,一个Socket,等等。这些控制都在一个小文件里,叫log4j.properties (其实你可以用其它名字,这里是默认名)。这个文件在工程目录下。以下是log4j.properties的内容:

#### Use one appender to log to console

log4j.rootCategory=DEBUG, stdout

#### Appender writes to console

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%5p (%F:%L) - %m%n

就是说我要显示所有优先权等於和高于Debug的信息,所以上面那个Class会显示Debug ...,Info ...,Warn ...,Error ...所有信息。

"stdout"表示我定义了一个输出端,叫stdout (随便什么名字都好)。

下面的三行说,这个stdout输出端其实是标准输出Console,也就是屏幕。输出的格式是Pattern。转换方式是%5p (%F:%L) - %m%n,即前五格用来显示优先权,再显示当前的文件名,加当前的行数。最后是logger.debug()或logger.info()或logger.warn()或logger.error()里的信息。%n表示回车空行。

运行程序,最后输出的是:

DEBUG (LogTest.java:9) - Debug ...

INFO (LogTest.java:10) - Info ...

WARN (LogTest.java:11) - Warn ...

ERROR (LogTest.java:12) - Error ...

搞了半天,最后就输出这么个东西? 对啊。有人就说了,"还不如System.out.println呢"。不过你看看,你做了些什么。

一、下载了log4j,copy类库到工程的lib目录

二、写一个log4j.properties文件 (4行)

三、在Class里加了"static Logger logger = Logger.getLogger(LogTest.class.getName());"一句话

四、用logger.xxx来输出信息。

完了。你得到的若干好处是:

一、在log4j.properties文件里把"log4j.rootCategory=DEBUG, stdout"改写成"log4j.rootCategory=OFF, stdout",这样所有的log信息都不会显示了;

二、在log4j.properties文件里把"log4j.rootCategory=DEBUG, stdout"改写成"log4j.rootCategory=INFO, stdout",这样只显示INFO, WARN, ERROR的log信息,而DEBUG信息不会被显示;

三、在log4j.properties文件里把"log4j.rootCategory=DEBUG, stdout"改写成"log4j.rootCategory=DEBUG, stdout, R",再加上下面三句话:

log4j.appender.R=org.apache.log4j.RollingFileAppender

log4j.appender.R.File=log.txt

log4j.appender.R.MaxFileSize=100KB

log4j.appender.R.MaxBackupIndex=1

log4j.appender.R.layout=org.apache.log4j.PatternLayout

log4j.appender.R.layout.ConversionPattern=%d{yyyy MMM dd HH:mm:ss} %-5p %c - %m%n

这样,你的log信息不光显示在屏幕上,而且将被保存在一个叫"log.txt"的文件里,文件最大为100KB。如果文件大小超过100KB,文件会被备份成"log.txt.1",新的"log.txt"继续记录log信息。

你可以改变log4j.properties,而不需重新编译就可以控制log信息是否显示、log信息的输出端类型、输出方式、输出格式,等等。你上面的四步工作带来这么多好处,我还要System.out.println来显示log信息吗? 不需要了。

 

以下是我LogTest项目的目录结构:

build.xml文件的内容:

<project

name="Log4j Test" default="build" basedir=".">

    <property name="app.home" value="${basedir}" />

    <property name="app.src" value="${app.home}/src" />

    <property name="app.bin" value="${app.home}/bin" />

    <property name="app.lib" value="${app.home}/lib" />

    <path id="classpath">

        <fileset dir="${app.lib}">

            <include name="**/*.jar" />

        </fileset>

        <path location="${app.home}"/>

        <path location="${app.bin}"/>

    </path>

    <target name="init">

        <mkdir dir="${app.bin}"/>

    </target>

    <target name="build" depends="init" description="compile the source " >

        <javac srcdir="${app.src}" destdir="${app.bin}">

            <classpath refid="classpath"/>

        </javac>

    </target>

    <target name="run" description="run">

        <java classname="LogTest" dir="${app.bin}" fork="true">

            <classpath refid="classpath"/>

        </java>

    </target>

    <target name="clean" description="clean up" >

        <delete dir="${app.bin}" />

    </target>

</project>

总共四个文件,一个用来测试的LogTest类,一个build.xml ANT文件,一个log4j.properties配制文件,一个log4j-1.2.8.jar类库。

log4j的功能有很多,doodoofish这里就不详细介绍了,以下是参考文献:

Don't Use System.out.println! Use Log4j by Vipan Singla

Build Flexible Logs With log4j by Vikram Goyal

log4j by Ashley J.S Mills, University Of Birmingham

Add logging to your Java Applications by Kevin Brown

How does the Java logging API stack up against log4j? by Kevin Brown

OpenSymphony Logging Primer

log4j FAQ at jGuru

 

Day2完挂,回家种田

RT. 88.
  • a2520123
  • a2520123
  • 2012年11月11日 18:52
  • 574

System.out.println内容写入txt

FileOutputStream bos = new FileOutputStream("output.txt");   System.setOut(new PrintStream(bos)...
  • KEKO150331027
  • KEKO150331027
  • 2016年03月01日 21:46
  • 171

system.out.println() 的结果写入文件中,换行

package com.test; import java.io.File; import java.io.FileOutputStream; import java.io.IOException;...
  • qyf_5445
  • qyf_5445
  • 2013年02月19日 14:34
  • 3968

回家过年感想

在外面漂泊的人,对于回家过年,向往而又畏惧 向往和父母和亲人相聚,畏惧...畏惧和向往的一样 这次回家过年和以前有所不同,已为人父 但,过程好像和往前一样 有些事情确实是我做的不好,但每次明知...
  • yangjiahui1006
  • yangjiahui1006
  • 2012年01月29日 18:28
  • 454

System.out.println() 输出中文乱码

System.out.println() 输出中文乱码 class Hello { public static void main(String[] args) { String...
  • pkuyjxu
  • pkuyjxu
  • 2012年04月24日 14:55
  • 6143

回家坐火车的感悟!

        难!真是太难了!早知道火车难挤,火车票难买,可是没想到会到这个地步。去火车站一看2号前所有的火车票已经基本售空了,剩的也是无座的票。做好最坏的打算去看汽车票,天可怜见——竟然还有票!兴...
  • wolfskytwl
  • wolfskytwl
  • 2007年03月02日 22:49
  • 488

2015年春节回家记实与感悟

一、圆梦:         因为孩子小,一直未回去过年,这次第一次带孩子过年,父母非常高兴,我也圆了一个梦,中国人传统节日“春节”,能陪父母聊聊天,回味下小时候的年味,让父母享受下        天伦...
  • wuxiaobingandbob
  • wuxiaobingandbob
  • 2015年02月27日 11:59
  • 753

度度熊回家

题目 一个数轴上共有N个点,第一个点的坐标是度度熊现在位置,第N-1个点是度度熊的家。现在他需要依次的从0号坐标走到N-1号坐标。 但是除了0号坐标和N-1号坐标,他可以在其余的N-2个坐标...
  • Double2hao
  • Double2hao
  • 2017年05月18日 10:57
  • 610

《王贵与安娜》剧情分集介绍(1--32) (图)

《王贵与安娜》剧情分集介绍(1--32) (图) 视频   改编自著名女作家六六同名小说的32集电视剧《王贵与安娜》,7月26日将登陆河北卫视晚间黄金档。该剧是六六的作品第二次搬上电视荧屏,在北京电视...
  • clubsondy
  • clubsondy
  • 2009年07月26日 21:33
  • 3646

回家过年的感受

这次回家过年感触及深,以前没有在过年的时候挤火车回家,这次回家的经历,让我想起了我的父亲每到年底回家过年,没有座位是怎么回来的。真的是不体验不知道,亲身经历了一下才能明白。             ...
  • u012752922
  • u012752922
  • 2014年02月10日 19:52
  • 758
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:让System.out.println回家种田
举报原因:
原因补充:

(最多只允许输入30个字)