If you look at this implementation
class Logger {
private final BufferedWriter w;
public Logger(final File file) throws IOException {
this.w = new BufferedWriter(new FileWriter(file));
LoggerRegistry.register(this);
}
public void log(String s) throws IOException {
synchronized (this.w) {
this.w.write(s);
this.w.write("\n");
}
}
public void close() throws IOException {
this.w.close();
}
}
the file is kept open.
If you have multiple threads, you have to synchronize in the write method (but this must be considered in any case).
There are possibly these problems, if the file remains open:
In theory, you could run out of file handles. These might be limited (see
ulimit -a
on Linux systems for example): Each logger consumes one handle.If you use a
FileWriter
without buffering, you have I/O calls for each invocation ofwrite
. This could be quite slow.If you use a
BufferedWriter
on top of aFileWriter
, you have to make sure that it gets closed properly at the end of your program, otherwise the remaining content in the buffer might not be written to the disk. So you need a try/finally block around your program which must close all loggers correctly.
Therefore you need to register all loggers. This is a simplified version (it is not thread-safe):
class LoggerRegistry {
private final static List<Logger> loggers = new ArrayList<Logger>();
public static void register(Logger l) {
loggers.add(l);
}
public static void close() {
for (Logger l : loggers) {
try {
l.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
and use this in your main program like this:
public static void main(String[] args) throws IOException {
try {
final Logger l = new Logger(new File("/tmp/1"));
l.log("Hello");
// ...
} finally {
LoggerRegistry.close();
}
}
If you have a web application, you could call the close
method in a ServletContextListener
(method contextDestroyed
).
The biggest performance gain is probably the BufferedWriter
. This advantage gets lost, if you open/close it for each write operation, since close
has to call flush
. So the combination of an open file together with buffering will be quite fast.