Home > other >  Why is StandardOpenOption.CREATE_NEW not creating a file to be read from in Java?
Why is StandardOpenOption.CREATE_NEW not creating a file to be read from in Java?

Time:07-18

Here is my code:

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class ExplicitChannelRead {

    public static void main(String[] args) {
        
        int count;
        Path filePath = null;
        
        // First, obtain a path to a file.
        try {
            filePath = Paths.get("test1.txt");
        }
        catch(InvalidPathException e) {
            System.out.println("Path error: " e);
            return;
        }
        
        // Next, obtain a channel to that file within a try-with-resources block.
        try(SeekableByteChannel fChan = 
                Files.newByteChannel(filePath, StandardOpenOption.CREATE_NEW)) {
            
            // Allocate a buffer.
            ByteBuffer mBuf = ByteBuffer.allocate(128);
            
            while((count=fChan.read(mBuf)) != -1) {
                
                //Rewind the buffer so that it can be read.
                mBuf.rewind();
                
                for(int i=0; i<count; i  ) System.out.print((char)mBuf.get());
                
            }
            
            System.out.println();
            
            
        } catch (IOException e) {
            e.printStackTrace();
//          System.out.println("I/O error: " e);
        }
        

    }

}

On running the above code I get this exception:

java.nio.file.NoSuchFileException: test1.txt
    at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85)
    at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
    at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
    at java.base/sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:235)
    at java.base/java.nio.file.Files.newByteChannel(Files.java:375)
    at java.base/java.nio.file.Files.newByteChannel(Files.java:426)
    at fileNIO.ExplicitChannelRead.main(ExplicitChannelRead.java:31)

I don't understand why test1.txt file is not being created as it doesn't exist currently and I am using the StandardOpenOption.CREATE_NEW option?

When I use StandardOpenOption.WRITE option along with StandardOpenOption.CREATE_NEW then I see the file text1.txt being created and at that time I get the exception:

Exception in thread "main" java.nio.channels.NonReadableChannelException

This exception I understand its cause because I have opened the file in write mode and in the code I am performing read operation on the file.

It seems to me that a new file can't be created when the file is opened in read mode.

CodePudding user response:

I have reproduced what you are seeing (on Linux with Java 17).

As I noted in the comments, the behavior seems to contradict what the javadocs say what should happen, but what I discovered is this:

  • With READ or neither READ or WRITE, a NoSuchFileException is thrown.

  • With WRITE (and no READ), the file is created by then NonReadableChannelException is thrown.

  • With both READ and WRITE, it works. At least ... it did for me.

I guess this sort of makes sense. You need READ to read the file and WRITE to create it. And the javadocs state that READ is the default if you don't specify READ, WRITE or APPEND.

And ... what you are doing (creating an empty file and trying to read it) is a use-case that borders on pointless, so it it not entirely surprising that they didn't (accurately) document how to do it.

  • Related