javanio与Windows磁盘访问

javanio与Windows磁盘访问,java,windows,file-permissions,nio,Java,Windows,File Permissions,Nio,Java NIO在Windows上是否需要特殊权限 当我在Windows Server 2003上运行以下Java代码时,它失败并出现“拒绝访问”错误(这是cygwin终端窗口中的全部消息): 但是,如果我使用Apache commons io(我假设它不使用NIO,它使用相同的输入和输出文件: final FileInputStream inputStream = new FileInputStream(inputFile) final FileOutputStream outputStrea

Java NIO在Windows上是否需要特殊权限

当我在Windows Server 2003上运行以下Java代码时,它失败并出现“拒绝访问”错误(这是cygwin终端窗口中的全部消息):

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

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

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

在什么上下文中执行?是否有使用同一文件的并发线程

如果是您的情况,则FileChannel会锁定正在使用的全部或部分文件。锁定方法(部分文件或全部文件)取决于平台格式,并且windows 2003可能已被此技术淘汰

解决方案:更改操作系统或使用apache commons IO


注意:如果您在一个请求中阻止了文件,但没有取消阻止,则必须重新启动jvm。

原因在代码中:

newfileoutputstream(outputFile).getChannel()
.transferFrom(新文件InputStream(inputFile).getChannel(),0,Long.MAX_值);

代码在几个层面上都是错误的

  • 如果没有关闭流,则异常很可能意味着文件无法写入。如果用户能够实际访问,“拒绝访问”类型的异常会导致资源泄漏(即未关闭),从而阻止任何其他操作完成

  • >p>您不能像W/O循环那样传输。虽然它将在Windows上工作,但是TeleTo/On不能同时读取/写入所有的东西。请考虑它与INStudio.Read(-)-OutPuthSo.WrreWe()相同,除了它可以使用由OS映射的DMA。

  • 在windows上,TransferTo/From是无用的,因为操作系统不支持它,因此它实际工作的原因是:它是模拟的。在Linux/Solaris/MacOS上,它可以只传输X字节,然后就可以完成了


这可能是一个JVM错误。您是否尝试过Java 6或7?目前无法升级。公司问题。输出文件是否在任何其他应用程序中打开?是否所有在某一时刻打开了该输出文件的应用程序都已关闭?Windows可能对其认为正在使用的文件有奇怪的问题。换句话说,请尝试重新启动计算机,然后运行该程序立即测试。公司政策是否阻止您使用Java 7测试此功能?它至少会让您知道这是一个bug还是一个功能。@sjngm:这失败了好几次(对于许多文件)。它们没有被任何其他应用程序打开。我对代码所做的唯一更改是使用commons io,然后重新运行。成功了。不确定NIO使用的内存映射IO是否是问题所在。该代码(复制文件)实际上只能在windows上运行。@请将注释引用到1rs点,将第二段引用到第三点()。你的答案投一票。抱歉,我的英语不好。顺便说一句,sun.io.ch(以及所有sun.**)代码都可用:我对Windows API不太熟悉。是否由于API缺少某些内容或尚未实现,因此传输到/从不起作用?@Ralph,Linux/Solaris函数名为sendile(2)/sendfile64,我不确定Windows。据我所知,最接近的是使用套接字的TransmitFile,但据我所知,JDK仍然不支持它。额外注意:WinAPI确实有CopyFileEx和CopyFile2,但它们适用于文件,而不是文件描述符。不过,我已经13年没有真正使用WinAPI了。
final FileInputStream inputStream = new FileInputStream(inputFile)
final FileOutputStream outputStream = new FileOutputStream(outputStream)
IOUtils.copy(inputStream, outputStream);