2012-10-02 16 views
5

que tiene el código de Java haciendo lo siguiente:java.nio.file.Files.isWriteable no está de acuerdo con java.io.File.canWrite()

  1. Cree un archivo vacío temporal con extensión ZIP utilizando File.createTempFile()
  2. Eliminar con File.delete() (que en realidad sólo queríamos que genere un nombre de archivo temporal)
  3. Copiar una "plantilla" archivo ZIP en el mismo camino con com.google.commons.io.ByteStreams.copy() usando un nuevo OutputSupplier dado el mismo nombre de archivo
  4. Modificar la postal archivo (eliminar un directo ORY) usando TrueZIP 7.4.3

En un sistema específico, paso 4 falla constantemente con FsReadOnlyArchiveFileSystemException - "This is a read-only archive file system!" (ver http://java.net/projects/truezip/lists/users/archive/2011-05/message/9)

Depuración del código TrueZIP, he notado lo siguiente:

  • Hay no hay ningún archivo abierto manejar en este archivo entre cualquiera de los pasos anteriores, y específicamente no antes del paso 4
  • Comprobando el mismo archivo con File.canWrite() en lugar de NIO regresa exactamente al mismo tiempo (utilizando un depurador), se muestra ese que se puede escribir

Aquí es lo que se ve en la lista de expresiones del depurador:

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 

El uso de JDK 1.7.04

¿Alguna idea?

+0

Me gustaría probar Java 7 actualización 7 para ver si se trata de un error que se ha solucionado. –

+0

Evitaría usar ambas API y, en su lugar, confiaré en las excepciones arrojadas, por ejemplo, por las API. 'nuevo FileOutputStream()'. – EJP

+0

no usaría java 7, para comenzar con – njzk2

Respuesta

3

Evitaría el uso de ambas API y, en cambio, confiaría en las excepciones arrojadas por, p. Ej. new FileOutputStream(). Al menos son reales y de verdadera preocupación. Usar las API que mencionas no tiene sentido, e introduce ventanas de tiempo y códigos repetidos. Debe capturar el IOException de todos modos: ¿por qué escribir todo ese código dos veces?

+0

Eso podría ser cierto, pero su respuesta no explica por qué los dos dan un resultado diferente en este caso. (vea el título) – Puce

+0

La prueba es parte del código TrueZIP en realidad y no se puede evitar porque, dependiendo del resultado, se le puede permitir escribir en el sistema de archivos virtual o no. –

+1

@Puce A veces, la respuesta a una pregunta es hacerlo de otra manera. – EJP

5

El resultado final no es demasiado sorprendente:

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

File.canWrite no presta atención a las ACL en absoluto y sólo comprueba el MS-DOS atributo de sólo lectura.

Files.isWriteable presta atención a las ACL pero por alguna razón (para mantener los programas rotos rotos?) Dejaron File.canWrite sin reparar. Esto resulta ser afortunado, porque en algunas situaciones parece que puede devolver falso incluso cuando puede abrir el archivo sin problemas.

Realmente, me gustaría resumir los métodos como éste:

  • File.canWrite veces retorna verdadero cuando en realidad no puede escribir en el archivo.
  • Files.isWriteable a veces devuelve falso cuando realmente puede escribir en el archivo.

No estoy seguro de cuál es el sentido de ninguno de los métodos en este momento. Dado que, en última instancia, todos los que los utilizan tienen que escribir un equivalente no roto que realmente intente abrir el archivo, uno se pregunta por qué no abrieron el archivo para realizar el control ellos mismos.

+0

Desde https://bugs.openjdk.java.net/browse/JDK-7190897 Files.isWritable funciona como se esperaba. –

+0

Creo que todavía es recomendable realizar simplemente la operación, en lugar de verificar y luego realizarla, porque el resultado de Files.isWritable está inmediatamente desactualizado, incluso si es correcto. Lo mismo ocurre con es Leíble, existe, notExists, isRegularFile, isDirectory, isSymbolicLink, y probablemente más. – Trejkaz

5

Hay un error en java.nio.file.Files.isWritable en windows: que no tendrá en cuenta los permisos implícitos. java bug #7190897

+3

Actualización: este error se corrigió en Java 8 (b84) y se transfirió a Java 7u40. –

Cuestiones relacionadas