【发布时间】:2023-03-05 03:30:01
【问题描述】:
我有以下代码:
@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 无法创建文件,除非它被打开以进行写入?
【问题讨论】:
标签: java nio filechannel