2011-10-14 43 views
7

Java NIO在Windows上需要特殊权限吗?Java NIO和Windows磁盘访问

当我运行Windows Server 2003上的Java代码,它失败“访问被拒绝”的错误(这是在cygwin终端窗口中的整个消息):

new FileOutputStream(outputFile).getChannel() 
    .transferFrom(new FileInputStream(inputFile).getChannel(), 0, Long.MAX_VALUE); 

,但如果我使用Apache公地-io(我假设不使用NIO,它与相同的输入和输出文件:

final FileInputStream inputStream = new FileInputStream(inputFile) 
final FileOutputStream outputStream = new FileOutputStream(outputStream) 
IOUtils.copy(inputStream, outputStream); 

我在Java 5中使用管理员帐户运行是否有必须设置一些特殊的文件权限

+0

它可能是一个JVM错误。你有没有试过Java 6或7? –

+0

目前无法升级。公司问题。 – Ralph

+0

是否在任何其他应用程序中打开outputFile?是否所有的应用程序都关闭了,这个outputFile在一个点上打开? Windows可能对它认为正在使用的文件有奇怪的问题。换句话说,尝试重新启动机器,然后立即运行该测试。 – sjngm

回答

4

的原因是在代码:

new FileOutputStream(outputFile).getChannel() .transferFrom(new FileInputStream(inputFile).getChannel(), 0, Long.MAX_VALUE);

的代码错了几级。

  • 没有关闭流,异常意味着很可能该文件不可用于写入。如果用户可以实际访问,“拒绝访问”类型的异常指向资源泄漏(即不关闭),这会阻止任何其他操作完成。

  • 你不能像那个不带循环那样转移。虽然它可以在Windows上运行,但transferTo/From不会一次读取/写入所有内容。考虑它与inputStream.read() - > outputStream.write()相同,除了它可以使用操作系统映射的DMA之外,它是相似的。

  • 由于操作系统不支持它,TransferTo/From在Windows上是无用的,因此它实际上起作用的原因是:它是模拟的。在Linux/Solaris/MacOS上,它可以传输X个字节并完成它。

+0

谢谢。很好的解释。 – Ralph

+0

顺便说一句,sun.io.ch(和所有的sun. ***)代码是可用的:http://download.java.net/openjdk/jdk6/ – bestsss

+0

我不是很熟悉Windows API。 TransferTo/From不起作用,因为API缺少某些东西或者它尚未实现? – Ralph

0

在什么情况下执行?并发线程是否使用同一个文件?

如果这是你的情况,FileChannel会锁定正在使用的全部或部分文件。锁定方法(部分文件或全部文件)取决于plataform,而且对于这种技术,windows 2003已经过时了。

解决方案:更改OS或使用apache commons IO。

注意:如果您在一个请求中阻止该文件并且未解除阻止,则必须重新启动jvm。

+0

该代码实际上不适用于任何窗口,但不能用于复制文件。 – bestsss

+0

@bestsss参考你的1rs点和第二段的注释引用你的第3点(http://docs.oracle.com/javase/6/docs/api/java/nio/channels/FileLock.html)。 一票为您的答案。我的英语不好,道歉。 – angelcervera