Java中StandardOpenOption.CREATE_NEW为何无法创建可读文件?
Java NIO 文件创建与读取问题分析
用户代码
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); } } }
首次运行异常
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)
用户疑问
- 明明使用了
StandardOpenOption.CREATE_NEW选项,为什么不存在test1.txt时文件没有被创建,反而抛出NoSuchFileException? - 当同时使用
WRITE和CREATE_NEW时,文件能被创建,但执行读取操作会抛出NonReadableChannelException,已理解该异常是因为写入模式无法读取,但想确认只读模式下无法创建新文件的原因。
问题原因与解决方案
1. 仅用CREATE_NEW无法创建文件的原因
Files.newByteChannel()方法如果只指定CREATE_NEW,默认的打开模式是只读。而创建新文件需要具备写入权限,只读模式下没有写入权限,因此CREATE_NEW无法生效,系统会认为文件不存在,抛出NoSuchFileException。
2. 正确的打开方式
如果需要创建新文件并读取它,必须同时指定CREATE_NEW、WRITE和READ三个选项:
try(SeekableByteChannel fChan = Files.newByteChannel(filePath, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE, StandardOpenOption.READ)) { // 后续读写逻辑 }
CREATE_NEW:确保文件不存在时创建,若已存在则抛出异常WRITE:赋予写入权限,让CREATE_NEW能成功创建文件READ:赋予读取权限,允许后续执行read()操作
补充说明
如果只是想读取已存在的文件,直接用StandardOpenOption.READ即可;如果想创建文件并写入,用CREATE_NEW+WRITE;读写都需要的话就三个选项组合使用。
内容的提问来源于stack exchange,提问作者Shri
相关产品推荐
相关产品推荐

