Java.nio.file.Files.isWriteable disagrees with java.io.File.canWrite ()

I have Java code that does the following:

  • Create a temporary empty file with the zip extension using File.createTempFile()
  • Delete it with File.delete()(we only wanted it to create a temp file name)
  • Copy the template zip file to the same path com.google.commons.io.ByteStreams.copy()using the new OutputSupplierfile with the same file name
  • Change the ZIP archive (delete the directory) with TrueZIP 7.4.3

On a specific system, step 4 does not work consistently with FsReadOnlyArchiveFileSystemException - "This is a read-only archive file system!"(see http://java.net/projects/truezip/lists/users/archive/2011-05/message/9 )

Debugging TrueZIP code, I noticed the following:

  • There is no open file descriptor in this file between any of the above steps, and especially not before step 4
  • Checking the same file with File.canWrite (), not NIO, returns with the same time (using the debugger), this shows that it is writable

Here is what you see in the list of debugger expressions:

fn => "C:/myworkdir/temp/myfile4088293380313057223tmp.zip"
java.nio.file.Files.isWritable(java.nio.file.Paths.get(fn)) => false
new java.io.File(fn).canWrite() => true

Using JDK 1.7.04

Any ideas?

+5
source share
3 answers

The end result is not too surprising:

java.nio.file.Files.isWritable(java.nio.file.Paths.get(fn)) => false
new java.io.File(fn).canWrite() => true

File.canWrite does not pay attention to the ACL at all and only checks the read attribute for MS-DOS only.

Files.isWriteable pays attention to the ACL, but for some reason (to break the broken programs?) They left the File.canWrite file uncommitted. This turns out to be successful, because in some situations it seems that it can return false, even if you can open the file without any problems.

Indeed, I would generalize the following methods:

  • File.canWrite true, .
  • Files.isWriteable false, .

, . , , , , , , .

+5

java.nio.file.files.isWritable : . java bug # 7190897

+5

I would avoid using both APIs and instead rely on exceptions thrown, for example. new FileOutputStream(). At least they are real and present a real problem. Using the APIs you mention is completely pointless, and it presents time windows and repeating code. In any case, you should catch IOException: why write all this code twice?

+3
source