[英]FileChannel.open(path, CREATE|CREATE_NEW) without WRITE option throws NoSuchFileException
我有以下代碼:
@Nonnull
@SneakyThrows
private Pair<InputStream, Long> probeSize(@Nonnull final InputStream image) {
final String tmpId = UUID.randomUUID().toString();
final File probeFile = new File(tmpDir, tmpId + ".jpg");
try (final FileChannel outChannel = FileChannel.open(probeFile.toPath(), CREATE);
final ReadableByteChannel innChannel = Channels.newChannel(image)) {
outChannel.transferFrom(innChannel, 0, Long.MAX_VALUE);
}
final Long fileSize = probeFile.length();
return Pair.of(new FileInputStream(probeFile), fileSize);
}
此代碼始終引發以下異常:
Caused by: java.nio.file.NoSuchFileException: /tmp/4bbc9008-e91c-4f18-b0f2-c61eed35066e.jpg
at sun.nio.fs.UnixException.translateToIOException(Unknown Source)
at sun.nio.fs.UnixException.rethrowAsIOException(Unknown Source)
at sun.nio.fs.UnixException.rethrowAsIOException(Unknown Source)
at sun.nio.fs.UnixFileSystemProvider.newFileChannel(Unknown Source)
查看FileChannel.open(path, option)
的 javadoc 和相關的StandardOpenOption
,沒有文檔暗示要創建文件,還必須打開它進行寫入。
唯一有效的選項:
FileChannel.open(probeFile.toPath(), CREATE, WRITE)
FileChannel.open(probeFile.toPath(), CREATE_NEW, WRITE)
我只是通過UnixChannelFactory.newFileChannel
確定了這一點,並注意到以下內容:
UnixChannelFactory:
protected static FileDescriptor open(int dfd,
UnixPath path,
String pathForPermissionCheck,
Flags flags,
int mode)
throws UnixException
{
// map to oflags
int oflags;
if (flags.read && flags.write) {
oflags = O_RDWR;
} else {
oflags = (flags.write) ? O_WRONLY : O_RDONLY;
}
if (flags.write) {
if (flags.truncateExisting)
oflags |= O_TRUNC;
if (flags.append)
oflags |= O_APPEND;
// create flags
if (flags.createNew) {
byte[] pathForSysCall = path.asByteArray();
// throw exception if file name is "." to avoid confusing error
if ((pathForSysCall[pathForSysCall.length-1] == '.') &&
(pathForSysCall.length == 1 ||
(pathForSysCall[pathForSysCall.length-2] == '/')))
{
throw new UnixException(EEXIST);
}
oflags |= (O_CREAT | O_EXCL);
} else {
if (flags.create)
oflags |= O_CREAT;
}
}
這表明,除非您指定WRITE
選項,否則將永遠不會創建該文件。
這是一個錯誤還是一個預期的功能, FileChannel.open
除非打開以進行寫入,否則無法創建文件?
我正在查看FileChannel.open(...)
的 JDK 7 Javadoc 。
該方法的文檔說:
READ
和WRITE
選項確定是否應打開文件進行讀取和/或寫入。 如果數組中不包含任何選項(或APPEND
選項),則打開文件進行讀取。
CREATE_NEW
的文檔說:
當文件只為閱讀而打開時,此選項將被忽略。
CREATE
的文檔說:
如果
CREATE_NEW
選項也存在或文件打開僅用於讀取,則忽略此選項。
將這三個片段放在一起,是的,這是預期的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.