javafilenionio2

Replace a file, if existing, or else create a new file, using NIO.2 in Java 7+


The Files.write & Files.writeString methods in Java 7+ are a concise handy way to write text to a file.

try
{
    Files.write (
            Paths.get ( "/Users/My_UserName/Example.txt" ) ,
            List.of( "Hello world" , Instant.now().toString() ) ,
            StandardCharsets.UTF_8 ,
            StandardOpenOption.WRITE ;
}
catch ( IOException e )
{
    throw new RuntimeException ( e );
}

Unfortunately, I cannot get this to work the first time, before the file exists. I get an exception thrown:

java.nio.file.NoSuchFileException

My goal is always blow away any existing file, to write a new fresh file.

I tried adding TRUNCATE_EXISTING.

try
{
    Files.write (
            Paths.get ( "/Users/My_UserName/Example.txt" ) ,
            List.of( "Hello world" , Instant.now().toString() ) ,
            StandardCharsets.UTF_8 ,
            StandardOpenOption.WRITE,
            StandardOpenOption.TRUNCATE_EXISTING );  // <--- Combining Open-options.
}
catch ( IOException e )
{
    throw new RuntimeException ( e );
}

But that too fails when the file does not already exist.

👉🏼 Is there some combination of OpenOption/StandardOpenOption objects to make use of these convenient Files methods?


Solution

  • CREATE, WRITE, & TRUNCATE_EXISTING

    So the behaviour you want is the effect of using CREATE, and TRUNCATE_EXISTING options with WRITE.

        Files.write (
                Paths.get ( "/Users/My_UserName/Example.txt" ) ,
                List.of ( "Hello world" , Instant.now ( ).toString ( ) ) ,
                StandardCharsets.UTF_8 ,
                StandardOpenOption.CREATE ,
                StandardOpenOption.WRITE ,
                StandardOpenOption.TRUNCATE_EXISTING
        );
    

    Fortunately, this is the default behaviour, as documented by both your API references like Files.write :

    If no options are present then this method works as if the CREATE, TRUNCATE_EXISTING, and WRITE options are present.

    So simply don’t override that default - don’t give that WRITE, so

        Files.write (
                Paths.get ( "/Users/My_UserName/Example.txt" ) ,
                List.of ( "Hello world" , Instant.now ( ).toString ( ) ) ,
                StandardCharsets.UTF_8  
                // <--- Omitting the 3 CREATE, WRITE, & TRUNCATE_EXISTING arguments.
        );
    

    Also, the Charset parameter is documented as optional, defaulting to UTF-8, in Java 8+ (but not the original Java 7 arrival of this class). So we can further shorten your code to this:

        Files.write (
                Paths.get ( "/Users/My_UserName/Example.txt" ) ,
                List.of ( "Hello world" , Instant.now ( ).toString ( ) ) 
                // <--- Omitting the StandardCharsets.UTF_8  argument.
                // <--- Omitting the 3 CREATE, WRITE, & TRUNCATE_EXISTING arguments.
        );