You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)

用户疑问

  1. 明明使用了StandardOpenOption.CREATE_NEW选项,为什么不存在test1.txt时文件没有被创建,反而抛出NoSuchFileException?
  2. 当同时使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 01:15:37