使用常见OpenOption组合的最快方法

16

有没有简洁、惯用的方式(可能使用Apache Commons),可以指定OpenOption的常见组合,例如StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING


常见的组合已经被指定为默认值。 - Franz Ebner
@franzebner 他们是吗? - Aleksandr Dubinsky
1
如下所列,是的它们是可选的 :) Files.new*中的OpenOptions是可选的,并且有预定义的默认值。 - Franz Ebner
3个回答

37

以下是您可以使用的简单方法。

使用静态导入来增加可读性:

import static java.nio.file.StandardOpenOption.CREATE_NEW;
import static java.nio.file.StandardOpenOption.WRITE;

OpenOption[] options = new OpenOption[] { WRITE, CREATE_NEW };

使用默认值:

     //no Options anyway
     Files.newBufferedReader(path, cs)

     //default: CREATE, TRUNCATE_EXISTING, and WRITE not allowed: READ
     Files.newBufferedWriter(path, cs, options)

     //default: READ not allowed: WRITE
     Files.newInputStream(path, options)

     //default: CREATE, TRUNCATE_EXISTING, and WRITE not allowed: READ
     Files.newOutputStream(path, options)

     //default: READ do whatever you want
     Files.newByteChannel(path, options)

最后,现在可以像这样指定选项集:

     Files.newByteChannel(path, EnumSet.of(CREATE_NEW, WRITE));

这些是很好的建议,谢谢!顺便问一下,你知道是否可以让这些方法创建必要的目录吗? - Aleksandr Dubinsky
作为提示:Files.createDirectories(dir, attrs)和Files.createDirectory(dir, attrs)!注意它们之间的区别。 - Franz Ebner
我的意思是,FileUtils.writeByteArrayToFile会在路径中创建不存在的目录,而Files.write则失败。 - Aleksandr Dubinsky
实现特定.. Apache Commons != JDK 7 SE! - Franz Ebner
什么是实现特定?我知道Commons不是JDK。我想知道是否有一种方法可以获得相同的行为。 - Aleksandr Dubinsky
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/44325/discussion-between-franz-ebner-and-aleksandr-dubinsky - Franz Ebner

7

我能提供的最好建议是欺骗T和T[]的等价性,另一个stackoverflow讨论中提到这应该可行。

我能在Java中将数组作为变量参数传递给方法吗?

所以...

OpenOption myOptions[] = {StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING};
OutputStream foo=OutputStream.newOutputStream(myPath,myOptions);

警告:未经测试。

这肯定会起作用。我有点希望Apache Commons或Guava已经完成了这个。但似乎很少有人在Java 7中使用NIO.2。 - Aleksandr Dubinsky
你可以给这个答案点赞,因为它是可行的,而且没有更好的选择。但是由于只有至少两个赞才能获得悬赏奖励,所以我不确定这会有什么影响。 - keshlam

3

java.nio.file.Files有五种方法可以使用OpenOption可变参数:

Files
    .newBufferedWriter(...)
    .write(...)
    .newOutputStream(...)
    .newInputStream(...) 
    .newByteChannel(...)

他们直接没有限制任何OpenOption组合,但它们在底层都调用了这三种方法中的某些方法:java.nio.file.spi.FileSystemProvider

FileSystemProvider
    .newInputStream(Path, OpenOption...)
    .newOutputStream(Path, OpenOption...)
    .newByteChannel(Path, Set<? extends OpenOption>, FileAttribute<?>...)

FileSystemProvider.newInputStream(...) 被以下方法调用:Files.newInputStream(...)

FileSystemProvider.newOutputStream(...) 被以下方法调用:

Files
    .newBufferedWriter(...)
    .newOutputStream(...)
    .write(...)

摘要:通过调用 FileSystemProvider.newByteChannel(...) 方法来执行以下操作:

  • Files.newByteChannel(...)
  • FileSystemProvider.newInputStream(...)
  • FileSystemProvider.newOutputStream(...)

OpenOption 组合限制如下:

  • FileSystemProvider.newInputStream(...)
    • 不支持写入(WRITE)或追加(APPEND)操作的抛出 UnsupportedOperationException 异常。
  • FileSystemProvider.newOutputStream(...)
    • 隐式执行写入(WRITE)操作。
    • 对读取(READ)操作抛出 IllegalArgumentException 异常。
    • 如果没有选项,则默认使用创建(CREATE)和截断现有文件(TRUNCATE_EXISTING)选项。

摘要FileSystemProvider.newByteChannel(...) 方法具有平台相关的实现,可能会扩展 OpenOption 组合限制(例如,sun.nio.fs.WindowsFileSystemProvider)。

所有使用 OpenOption 可变参数的文件方法最终都会调用抽象的 FileSystemProvider.newByteChannel(...) 方法,其实现是平台相关的。因此,文件方法中的 OpenOption 组合限制也是平台相关的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接