📄 filehandler.java
字号:
/* * @(#)FileHandler.java 1.26 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package java.util.logging;import java.io.*;import java.nio.channels.FileChannel;import java.nio.channels.FileLock;import java.security.*;/** * Simple file logging <tt>Handler</tt>. * <p> * The <tt>FileHandler</tt> can either write to a specified file, * or it can write to a rotating set of files. * <p> * For a rotating set of files, as each file reaches a given size * limit, it is closed, rotated out, and a new file opened. * Successively older files are named by adding "0", "1", "2", * etc into the base filename. * <p> * By default buffering is enabled in the IO libraries but each log * record is flushed out when it is complete. * <p> * By default the <tt>XMLFormatter</tt> class is used for formatting. * <p> * <b>Configuration:</b> * By default each <tt>FileHandler</tt> is initialized using the following * <tt>LogManager</tt> configuration properties. If properties are not defined * (or have invalid values) then the specified default values are used. * <ul> * <li> java.util.logging.FileHandler.level * specifies the default level for the <tt>Handler</tt> * (defaults to <tt>Level.ALL</tt>). * <li> java.util.logging.FileHandler.filter * specifies the name of a <tt>Filter</tt> class to use * (defaults to no <tt>Filter</tt>). * <li> java.util.logging.FileHandler.formatter * specifies the name of a </tt>Formatter</tt> class to use * (defaults to <tt>java.util.logging.XMLFormatter</tt>) * <li> java.util.logging.FileHandler.encoding * the name of the character set encoding to use (defaults to * the default platform encoding). * <li> java.util.logging.FileHandler.limit * specifies an approximate maximum amount to write (in bytes) * to any one file. If this is zero, then there is no limit. * (Defaults to no limit). * <li> java.util.logging.FileHandler.count * specifies how many output files to cycle through (defaults to 1). * <li> java.util.logging.FileHandler.pattern * specifies a pattern for generating the output file name. See * below for details. (Defaults to "%h/java%u.log"). * <li> java.util.logging.FileHandler.append * specifies whether the FileHandler should append onto * any existing files (defaults to false). * </ul> * <p> * <p> * A pattern consists of a string that includes the following special * components that will be replaced at runtime: * <ul> * <li> "/" the local pathname separator * <li> "%t" the system temporary directory * <li> "%h" the value of the "user.home" system property * <li> "%g" the generation number to distinguish rotated logs * <li> "%u" a unique number to resolve conflicts * <li> "%%" translates to a single percent sign "%" * </ul> * If no "%g" field has been specified and the file count is greater * than one, then the generation number will be added to the end of * the generated filename, after a dot. * <p> * Thus for example a pattern of "%t/java%g.log" with a count of 2 * would typically cause log files to be written on Solaris to * /var/tmp/java0.log and /var/tmp/java1.log whereas on Windows 95 they * would be typically written to to C:\TEMP\java0.log and C:\TEMP\java1.log * <p> * Generation numbers follow the sequence 0, 1, 2, etc. * <p> * Normally the "%u" unique field is set to 0. However, if the <tt>FileHandler</tt> * tries to open the filename and finds the file is currently in use by * another process it will increment the unique number field and try * again. This will be repeated until <tt>FileHandler</tt> finds a file name that * is not currently in use. If there is a conflict and no "%u" field has * been specified, it will be added at the end of the filename after a dot. * (This will be after any automatically added generation number.) * <p> * Thus if three processes were all trying to log to fred%u.%g.txt then * they might end up using fred0.0.txt, fred1.0.txt, fred2.0.txt as * the first file in their rotating sequences. * <p> * Note that the use of unique ids to avoid conflicts is only guaranteed * to work reliably when using a local disk file system. * * @version 1.26, 01/23/03 * @since 1.4 */public class FileHandler extends StreamHandler { private MeteredStream meter; private boolean append; private int limit; // zero => no limit. private int count; private String pattern; private String lockFileName; private FileOutputStream lockStream; private File files[]; private static final int MAX_LOCKS = 100; private static java.util.HashMap locks = new java.util.HashMap(); // A metered stream is a subclass of OutputStream that // (a) forwards all its output to a target stream // (b) keeps track of how many bytes have been written private class MeteredStream extends OutputStream { OutputStream out; int written; MeteredStream(OutputStream out, int written) { this.out = out; this.written = written; } public void write(int b) throws IOException { out.write(b); written++; } public void write(byte buff[]) throws IOException { out.write(buff); written += buff.length; } public void write(byte buff[], int off, int len) throws IOException { out.write(buff,off,len); written += len; } public void flush() throws IOException { out.flush(); } public void close() throws IOException { out.close(); } } private void open(File fname, boolean append) throws IOException { int len = 0; if (append) { len = (int)fname.length(); } FileOutputStream fout = new FileOutputStream(fname.toString(), append); BufferedOutputStream bout = new BufferedOutputStream(fout); meter = new MeteredStream(bout, len); setOutputStream(meter); } // Private method to configure a FileHandler from LogManager // properties and/or default values as specified in the class // javadoc. private void configure() { LogManager manager = LogManager.getLogManager(); String cname = FileHandler.class.getName(); pattern = manager.getStringProperty(cname + ".pattern", "%h/java%u.log"); limit = manager.getIntProperty(cname + ".limit", 0); if (limit < 0) { limit = 0; } count = manager.getIntProperty(cname + ".count", 1); if (count <= 0) { count = 1; } append = manager.getBooleanProperty(cname + ".append", false); setLevel(manager.getLevelProperty(cname + ".level", Level.ALL)); setFilter(manager.getFilterProperty(cname + ".filter", null)); setFormatter(manager.getFormatterProperty(cname + ".formatter", new XMLFormatter())); try { setEncoding(manager.getStringProperty(cname +".encoding", null)); } catch (Exception ex) { try { setEncoding(null); } catch (Exception ex2) { // doing a setEncoding with null should always work. // assert false; } } } /** * Construct a default <tt>FileHandler</tt>. This will be configured * entirely from <tt>LogManager</tt> properties (or their default values). * <p> * @exception IOException if there are IO problems opening the files. * @exception SecurityException if a security manager exists and if * the caller does not have <tt>LoggingPermission("control"))</tt>. */ public FileHandler() throws IOException, SecurityException { checkAccess(); configure(); openFiles(); } /** * Initialize a <tt>FileHandler</tt> to write to the given filename. * <p> * The <tt>FileHandler</tt> is configured based on <tt>LogManager</tt> * properties (or their default values) except that the given pattern * argument is used as the filename pattern, the file limit is * set to no limit, and the file count is set to one. * <p> * There is no limit on the amount of data that may be written, * so use this with care. * * @param pattern the name of the output file * @exception IOException if there are IO problems opening the files. * @exception SecurityException if a security manager exists and if * the caller does not have <tt>LoggingPermission("control")</tt>. */ public FileHandler(String pattern) throws IOException, SecurityException { checkAccess(); configure(); this.pattern = pattern; this.limit = 0; this.count = 1; openFiles(); } /** * Initialize a <tt>FileHandler</tt> to write to the given filename, * with optional append. * <p> * The <tt>FileHandler</tt> is configured based on <tt>LogManager</tt> * properties (or their default values) except that the given pattern * argument is used as the filename pattern, the file limit is * set to no limit, the file count is set to one, and the append * mode is set to the given <tt>append</tt> argument. * <p> * There is no limit on the amount of data that may be written, * so use this with care. * * @param pattern the name of the output file * @param append specifies append mode * @exception IOException if there are IO problems opening the files. * @exception SecurityException if a security manager exists and if * the caller does not have <tt>LoggingPermission("control")</tt>. */ public FileHandler(String pattern, boolean append) throws IOException, SecurityException { checkAccess(); configure(); this.pattern = pattern; this.limit = 0; this.count = 1; this.append = append; openFiles(); } /** * Initialize a <tt>FileHandler</tt> to write to a set of files. When * (approximately) the given limit has been written to one file, * another file will be opened. The output will cycle through a set * of count files. * <p> * The <tt>FileHandler</tt> is configured based on <tt>LogManager</tt> * properties (or their default values) except that the given pattern * argument is used as the filename pattern, the file limit is * set to the limit argument, and the file count is set to the * given count argument. * <p> * The count must be at least 1. * * @param pattern the pattern for naming the output file * @param limit the maximum number of bytes to write to any one file * @param count the number of files to use * @exception IOException if there are IO problems opening the files. * @exception SecurityException if a security manager exists and if * the caller does not have <tt>LoggingPermission("control")</tt>. * @exception IllegalArgumentException if limit < 0, or count < 1. */ public FileHandler(String pattern, int limit, int count) throws IOException, SecurityException { if (limit < 0 || count < 1) { throw new IllegalArgumentException(); } checkAccess(); configure(); this.pattern = pattern; this.limit = limit; this.count = count; openFiles(); } /**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -