I recently discovered that due to backward compatibility with DOS, the Windows OS has some reserved keywords that cannot be created in the file system, since these were originally used to write streams of data to other hardware like printers. Microsoft states that you cannot name a folder nor a file (regardless of extension) with the following reserved keywords: CON, PRN, AUX, NUL, COM0, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT0, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9
. If you try to create one of these in Windows explorer you should receive the error message "the specified device name is invalid".
However, using Windows Explorer (Windows 11) I was actually able to create all of them as files as long as they had an extension, and I could create some of the folders named COM0
-COM9
.
I wanted to know if there were any safeguards to help avoid accidentally creating these folders in Java, and first checked if the java.io.File
or java.nio.file.Path
classes would throw exceptions like InvalidPathException
when trying to store any of these reserved keywords. No exceptions were thrown.
So then I was curious to see if I could use File.mkdir
(and Files.createDirectories
) to create any of these invalid files, and I could. In fact they all returned true
for success, and I can view them all in Windows Explorer fine, except for NUL
which seems to be the only case that wasn't created.
My question is, are there any risks on modern Windows when creating one of these 'illegal" names? Why doesn't Microsoft's own documentation match my results, is it a recent update in Windows 11? What kinds of bugs might happen or go unnoticed if I don't add my own safeguards? Are Unix/macOS plagued with any of these reserved keywords?
Here is a passing unit test:
@Test
public void test() throws IOException {
Path dirTest = Paths.get("C:\\Testing");
File fNul = dirTest.resolve("NUL").toFile();
assertTrue(fNul.mkdir());
assertFalse(fNul.exists()); //The only one impossible to create
String[] vKeywords = {"CON", "PRN", "AUX" };
for (String s : vKeywords) {
File f = dirTest.resolve(s).toFile();
assertTrue(f.mkdir());
assertTrue(f.exists() || s.equals("NUL"));
}
String[] vPrefixes = {"COM", "LPT" };
for (String s : vPrefixes) {
for (int i = 0; i < 10; i++) { // 0-9 suffix
File f = dirTest.resolve(s + i).toFile();
assertTrue(f.mkdir());
assertTrue(f.exists());
}
}
}