Java 7: StandardOpenOption Enum
When performing file I/O operations, developers need precise control over how a file is accessed and modified. Should a new file be created if it doesn't exist? Should existing data be overwritten or preserved? Before Java 7, specifying these behaviors often involved using boolean flags in legacy FileOutputStream or FileWriter constructors (e.g., passing true for append mode), which was not very expressive or flexible.
With the introduction of the NIO.2 API, Java 7 provided a much more robust and readable way to configure file access via the java.nio.file.StandardOpenOption enum. This enumeration defines a comprehensive set of options that dictate exactly how a file should be opened by classes like Files, FileChannel, or AsynchronousFileChannel. By passing one or more of these options as a varargs parameter to I/O methods, developers can combine behaviors with granular precision.
Common options include READ and WRITE for basic access, APPEND to add data to the end of a file, CREATE to make a new file if it's missing, and CREATE_NEW to create a file but fail if it already exists (preventing accidental overwrites). Furthermore, it includes advanced options like TRUNCATE_EXISTING, which wipes the file content upon opening, and DELETE_ON_CLOSE, which is incredibly useful for managing temporary files.
Using StandardOpenOption makes the intent of the code immediately obvious. Instead of relying on obscure boolean parameters or complex logic checks before opening a stream, the combinations of enum values explicitly document the required file system state and the intended operation, leading to safer and more maintainable code.
How it Works
Many methods in the Files class, such as Files.write(), Files.newOutputStream(), or Files.newByteChannel(), accept a variable number of OpenOption arguments. You provide the desired StandardOpenOption enum values separated by commas to combine their effects.
Java Example
Scenario 1: Appending vs Overwriting
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.io.IOException;
import java.util.Arrays;
public class OpenOptionExample1 {
public static void main(String[] args) {
Path path = Paths.get("data.txt");
try {
// Write and TRUNCATE (overwrite) existing content
Files.write(path, Arrays.asList("Initial Line"), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
System.out.println("File created/truncated.");
// APPEND to the file without overwriting
Files.write(path, Arrays.asList("Appended Line"), StandardOpenOption.APPEND);
System.out.println("Line appended.");
Files.readAllLines(path).forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output
File created/truncated.
Line appended.
Initial Line
Appended Line
Scenario 2: Strict File Creation (CREATE_NEW)
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
public class OpenOptionExample2 {
public static void main(String[] args) {
Path newFile = Paths.get("unique_config.txt");
try {
// Ensure the file is created ONLY if it doesn't exist
Files.write(newFile, "Config Data".getBytes(), StandardOpenOption.CREATE_NEW);
System.out.println("File created successfully.");
// Attempting to create it again with CREATE_NEW will fail
Files.write(newFile, "More Data".getBytes(), StandardOpenOption.CREATE_NEW);
} catch (FileAlreadyExistsException e) {
System.out.println("Error: File already exists! Preventing overwrite.");
} catch (IOException e) {
e.printStackTrace();
} finally {
try { Files.deleteIfExists(newFile); } catch (Exception ex) {} // cleanup
}
}
}
Output
File created successfully.
Error: File already exists! Preventing overwrite.
Scenario 3: Temporary Files with DELETE_ON_CLOSE
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.io.OutputStream;
import java.io.IOException;
public class OpenOptionExample3 {
public static void main(String[] args) {
Path tempPath = Paths.get("temp_workspace.txt");
try (OutputStream os = Files.newOutputStream(tempPath,
StandardOpenOption.CREATE,
StandardOpenOption.WRITE,
StandardOpenOption.DELETE_ON_CLOSE)) {
os.write("Temporary processing data...".getBytes());
System.out.println("Temp file written. Does it exist? " + Files.exists(tempPath));
} catch (IOException e) {
e.printStackTrace();
}
// Outside the try-with-resources block, the stream is closed, triggering the deletion
System.out.println("Stream closed. Does it exist now? " + Files.exists(tempPath));
}
}
Output
Temp file written. Does it exist? true
Stream closed. Does it exist now? false
Key Points
- Provides a highly expressive way to configure file I/O operations via an enum.
- Allows combining behaviors like creating, appending, and truncating.
CREATE_NEWprevents accidental overwrites by throwing an exception if the file exists.DELETE_ON_CLOSEis ideal for managing lifecycle-bound temporary files automatically.
Comments