3

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.

6
  • Umm ... if you have just created the file, what do you expect to read from it? It will be empty. Commented Jul 18, 2022 at 7:37
  • Yes, test1.txt would be empty but then I should not be getting that exception: java.nio.file.NoSuchFileException: test1.txt , right? Commented Jul 18, 2022 at 7:46
  • No you shouldn't. According to the javadoc (and my reading of the code) the file should be opened for read, since you don't specify either WRITE or APPEND. So you shouldn't get NonReadableChannelException. However, >I think< you could get NoSuchFileException if you try to create a file in a directory that does not exist. Please add the complete stacktraces for the 2 exceptions to the question. Commented Jul 18, 2022 at 7:55
  • I am using JDK 8 and I have added the complete stack trace of the issue above. Commented Jul 18, 2022 at 8:07
  • The combination of CREATE_NEW and read access seems pointless to me, as it there's only ever two possible outcomes (even hypothetically, if you follow the docs, ignoring platform specifics): Either the file existed before, then you'll get an error or the file didn't exist then you'll get an empty file that's just opened for reading. Commented Jul 18, 2022 at 8:14

1 Answer 1

5

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 but 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.

But creating an empty file1 with CREATE_NEW and then immediately trying to read it is a use-case that borders on pointless. So it not entirely surprising that they didn't (clearly) document how to achieve this.


1 - As a comment noted, CREATE_NEW is specified to fail if the file already exists. If you want "create it if it doesn't exist", then you should use CREATE instead.

Sign up to request clarification or add additional context in comments.

2 Comments

Yeah, I agree that the docs don't show that both READ and WRITE options are required to create a file. Now I am able to create a file if it doesn't exist already. Thanks, Stephen.
@Shri: You say you want to create the file if it doesn't exist, but that's not what CREATE_NEW does! It creates the file and fails if it already exists! If you want to create or read the existing one, use CREATE instead. That's also why CREATE_NEW makes even less sense in combination with reading than CREATE does ...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.