src/share/classes/java/util/logging/FileHandler.java
Print this page
@@ -23,14 +23,23 @@
* questions.
*/
package java.util.logging;
-import java.io.*;
+import static java.nio.file.StandardOpenOption.CREATE_NEW;
+import static java.nio.file.StandardOpenOption.WRITE;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
import java.nio.channels.FileChannel;
-import java.nio.channels.FileLock;
-import java.security.*;
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.Paths;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
/**
* Simple file logging <tt>Handler</tt>.
* <p>
* The <tt>FileHandler</tt> can either write to a specified file,
@@ -135,18 +144,20 @@
private boolean append;
private int limit; // zero => no limit.
private int count;
private String pattern;
private String lockFileName;
- private FileOutputStream lockStream;
+ private FileChannel lockFileChannel;
private File files[];
private static final int MAX_LOCKS = 100;
private static java.util.HashMap<String, String> 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
+ /**
+ * 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) {
@@ -187,13 +198,14 @@
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.
+ /**
+ * 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 = getClass().getName();
@@ -285,11 +297,12 @@
* @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 pattern is an empty string
*/
- public FileHandler(String pattern, boolean append) throws IOException, SecurityException {
+ public FileHandler(String pattern, boolean append) throws IOException,
+ SecurityException {
if (pattern.length() < 1 ) {
throw new IllegalArgumentException();
}
checkPermission();
configure();
@@ -374,12 +387,14 @@
this.count = count;
this.append = append;
openFiles();
}
- // Private method to open the set of output files, based on the
- // configured instance variables.
+ /**
+ * Open the set of output files, based on the configured
+ * instance variables.
+ */
private void openFiles() throws IOException {
LogManager manager = LogManager.getLogManager();
manager.checkPermission();
if (count < 1) {
throw new IllegalArgumentException("file count = " + count);
@@ -411,22 +426,22 @@
if (locks.get(lockFileName) != null) {
// We already own this lock, for a different FileHandler
// object. Try again.
continue;
}
- FileChannel fc;
+
try {
- lockStream = new FileOutputStream(lockFileName);
- fc = lockStream.getChannel();
- } catch (IOException ix) {
- // We got an IOException while trying to open the file.
- // Try the next file.
+ lockFileChannel = FileChannel.open(Paths.get(lockFileName),
+ CREATE_NEW, WRITE);
+ } catch (FileAlreadyExistsException ix) {
+ // try the next lock file name in the sequence
continue;
}
+
boolean available;
try {
- available = fc.tryLock() != null;
+ available = lockFileChannel.tryLock() != null;
// We got the lock OK.
} catch (IOException ix) {
// We got an IOException while trying to get the lock.
// This normally indicates that locking is not supported
// on the target directory. We have to proceed without
@@ -438,11 +453,11 @@
locks.put(lockFileName, lockFileName);
break;
}
// We failed to get the lock. Try next file.
- fc.close();
+ lockFileChannel.close();
}
}
files = new File[count];
for (int i = 0; i < count; i++) {
@@ -470,12 +485,21 @@
// Install the normal default ErrorManager.
setErrorManager(new ErrorManager());
}
- // Generate a filename from a pattern.
- private File generate(String pattern, int generation, int unique) throws IOException {
+ /**
+ * Generate a file based on a user-supplied pattern, generation number,
+ * and an integer uniqueness suffix
+ * @param pattern the pattern for naming the output file
+ * @param generation the generation number to distinguish rotated logs
+ * @param unique a unique number to resolve conflicts
+ * @return the generated File
+ * @throws IOException
+ */
+ private File generate(String pattern, int generation, int unique)
+ throws IOException {
File file = null;
String word = "";
int ix = 0;
boolean sawg = false;
boolean sawu = false;
@@ -546,11 +570,13 @@
}
}
return file;
}
- // Rotate the set of output files
+ /**
+ * Rotate the set of output files
+ */
private synchronized void rotate() {
Level oldLevel = getLevel();
setLevel(Level.OFF);
super.close();
@@ -613,29 +639,30 @@
// Unlock any lock file.
if (lockFileName == null) {
return;
}
try {
- // Closing the lock file's FileOutputStream will close
- // the underlying channel and free any locks.
- lockStream.close();
+ // Close the lock file channel (which also will free any locks)
+ lockFileChannel.close();
} catch (Exception ex) {
// Problems closing the stream. Punt.
}
synchronized(locks) {
locks.remove(lockFileName);
}
new File(lockFileName).delete();
lockFileName = null;
- lockStream = null;
+ lockFileChannel = null;
}
private static class InitializationErrorManager extends ErrorManager {
Exception lastException;
public void error(String msg, Exception ex, int code) {
lastException = ex;
}
}
- // Private native method to check if we are in a set UID program.
+ /**
+ * check if we are in a set UID program.
+ */
private static native boolean isSetUID();
}