我有一个自定义Logger
类:
import java.io.OutputStream;
import java.io.PrintStream;
public class Logger extends PrintStream{
public Logger(OutputStream outputStream) {
super(outputStream);
logHeader();
}
private void logHeader(){
for (int i=0; i<20; i++) print("#");
print("Program execution start: ");
print(CalendarClock.getInitTimeStamp());
for (int i=0; i<20; i++) print("#");
println();
}
public void logFooter(){
for (int i=0; i<=20; i++) print("#");
print("Program execution stop: ");
print(CalendarClock.getCurrentTimeStamp());
for (int i=0; i<=20; i++) print("#");
println("\n");
}
@Override
public void print(String arg0) {
super.print(arg0);
if (this.out != System.out) System.out.print(arg0);
}
@Override
public void println(String arg0) {
super.println(arg0);
if (this.out != System.out) System.out.println(arg0);
}
}
这是我的main
课程:
public class Main {
@SuppressWarnings("resource")
public static void main(String[] args){
File logFile = new File("data/test.log");
Logger logger;
try{
if (!logFile.exists()) logFile.createNewFile();
logger = new Logger(new FileOutputStream(logFile, false));
} catch (IOException e) {
logger = new Logger(System.out);
}
logger.println("Hello World.");
logger.println("Foo Bar");
logger.logFooter();
logger.close();
}
}
首先,Eclipse会在logger = new Logger(System.out);
catch(IOException e)
内的Resource leak: 'logger' is not closed at this location
处显示警告。我必须添加@SuppressWarnings("resource")
才能让它消失。
其次,该程序将以下内容输出到控制台:
####################Program execution start: 2015-10-27 10:55:51####################Hello World.Hello World.
Foo BarFoo Bar
#####################Program execution stop: 2015-10-27 10:55:51#####################
当它正确记录到文件时:
####################Program execution start: 2015-10-27 10:55:51####################
Hello World.
Foo Bar
#####################Program execution stop: 2015-10-27 10:55:51#####################
最后,如果我运行以下代码:
public class Main {
@SuppressWarnings("resource")
public static void main(String[] args){
File logFile = new File("data/test.log");
Logger logger;
try{
throw new IOException("Threw the exception!");
/*if (!logFile.exists()) logFile.createNewFile();
logger = new Logger(new FileOutputStream(logFile, false));*/
} catch (IOException e) {
logger = new Logger(System.out);
logger.println(e.getMessage());
}
logger.println("Hello World.");
logger.println("Foo Bar");
logger.logFooter();
logger.close();
}
}
输出正确打印为:
####################Program execution start: 2015-10-27 10:59:18####################
Threw the exception!
Hello World.
Foo Bar
#####################Program execution stop: 2015-10-27 10:59:18#####################
显然,这一切似乎都超出了我的理解范围,对此行为的任何解释都将受到赞赏。
更新
我通过覆盖空参数println
解决了标题末尾没有新行的问题:
@Override
public void println() {
super.println();
if (out != System.out) System.out.println();
}
现在第一个main
的输出是:
####################Program execution start: 2015-10-27 11:15:30####################
Hello World.Hello World.
Foo BarFoo Bar
#####################Program execution stop: 2015-10-27 11:15:30#####################
答案 0 :(得分:0)
我使用调试器查看代码执行的顺序,发现PrintStream
类实现了prinln(arg0)
作为对print(arg0)
和newline()
的调用,这相当于println()
。因此,每次在println(arg0)
中调用Logger
时,arg0
都会打印到stdout
两次,一次在print(arg0)
,一次在println(arg0)
。
为了克服我的问题,我将println(arg0)
课程中Logger
的实施更改为:
@Override
public void println(String arg0) {
print(arg0);
println();
}