While Although creating a file is generally accomplished with a single method call, it actually has several issues to consider. What should be done if the file cannot be created? What should be done if the file already exists? What should hte be the file's initial attributes, such as permissions, be? Java provides a mishmash of methods to handle fine-grained control of file creation.
...
This noncompliant code example tries to open a file for writing.:
Code Block | ||||
---|---|---|---|---|
| ||||
String filename = // nameName of file to write OutputStream out = new FileOutputStream(filename); // workWork with FILE |
If the file existed before being opened, its former contents will be overwritten with the contents provided by the program.
...
This noncompliant code example tries to avoid clobbering an existing file:
Code Block | ||||
---|---|---|---|---|
| ||||
String filename = // nameName of file to write OutputStream out = new FileOutputStream(filename, true); // workWork with FILE |
If the file existed before being opened, its new contents will be appended to the former contents. This code is compliant only if this was the intention of the programmer.
...
This noncompliant code example tries to avoid altering an existing file by creating an empty file using File.createNewfile()
. If a file with the given name already exists, then File.createNewFile()
will return false
.
Code Block | ||||
---|---|---|---|---|
| ||||
OutputStream out = new FileOutputStream(filename, true); if (!new File(filename).createNewFile()) { // fileFile cannot be created...handle error } else { OutputStream out = new FileOutputStream(filename); // workWork with FILE } |
Unfortunately, this solution is subject to a TOCTOU (time-of-check-time-of-use) race condition. It is possible for an attacker to modify the filesystem file system such that the file that is created is not the file that gets is opened.
Compliant Solution (Files
)
This compliant solution uses the Files.newOutputStream()
function to atomically create the file and throw an exception if the file already exists.:
Code Block | ||||
---|---|---|---|---|
| ||||
try (OutputStream out = new BufferedOutputStream( Files.newOutputStream( Paths.get(filename), StandardOpenOption.CREATE_NEW))) { // workWork with out } catch (IOException x) { // fileFile not writable...handle error } |
...
The ability to determine if an existing file has been opened or a new file has been created provides greater assurance that a file other than the intended file is not opened or clobbered.
...