Are null characters in java.io.File valid for exists check?
If using JDK 1.7+ the java.nio.files.Paths.get(URI) can be used to test for Nul (it seems)
A modification to the original tests produces a useful Exception
package os;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class FileNullCheck
{
public static void main(String[] args) throws Exception
{
File tmp = new File("a.txt");
try
{
tmp.createNewFile();
}
catch (IOException e)
{
e.printStackTrace();
return;
}
String a = "a.txt";
testExists("a.txt", a);
String anull = new String(new byte[] { 'a', '.', 't', 'x', 't', 0x00 }, "UTF-8");
testExists("a.txt (null)", anull);
String anullx = new String(new byte[] { 'a', '.', 't', 'x', 't', 0x00, 'x' }, "UTF-8");
testExists("a.txt (nullx)", anullx);
}
private static void testExists(String label, String filename) throws IOException
{
File file = new File(filename);
System.out.printf("%s exists: %b%n", label, file.exists());
System.out.printf(" filename.length = %d%n", filename.length());
Path path = Paths.get(file.toURI());
boolean symlink = Files.isSymbolicLink(path);
System.out.printf(" nio issymlink = %b%n",symlink);
}
}
Results in the output
a.txt exists: true filename.length = 5 nio issymlink = false a.txt (null) exists: true filename.length = 6 Exception in thread "main" java.nio.file.InvalidPathException: Nul character not allowed: /home/joakim/code/Stackoverflow/a.txt at sun.nio.fs.UnixPath.checkNotNul(UnixPath.java:93) at sun.nio.fs.UnixPath.normalizeAndCheck(UnixPath.java:83) at sun.nio.fs.UnixPath.(UnixPath.java:71) at sun.nio.fs.UnixFileSystem.getPath(UnixFileSystem.java:281) at java.io.File.toPath(File.java:2069) at sun.nio.fs.UnixUriUtils.fromUri(UnixUriUtils.java:61) at sun.nio.fs.UnixFileSystemProvider.getPath(UnixFileSystemProvider.java:97) at java.nio.file.Paths.get(Paths.java:138) at os.FileNullCheck.testExists(FileNullCheck.java:39) at os.FileNullCheck.main(FileNullCheck.java:28)
On RHEL it appears that the nul byte terminates the file name (as you might expect in C)
System.out.println("a exists " + new File("a").exists());
FileOutputStream fos = new FileOutputStream(new File("a\u0000aa"));
fos.close();
System.out.println("a exists " + new File("a").exists());
prints
a exists false
a exists true
I suspect Java should prevent you from attempting to use a file name with a nul byte.