2012-05-10 17 views
10

Estaba probando JCIFS para acceder a recursos compartidos de Windows. Es muy lento hasta el punto de ser completamente inutilizable.JCIFS: la recuperación de archivos es demasiado lenta para ser utilizable

import jcifs.smb.*; 

class First { 
    public static void main(String[] args) throws Exception { 
    try { 
     //jcifs.Config.setProperty("jcifs.netbios.wins", "192.168.1.220"); 
     NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("domain.com", "Administrator", "password"); 

     SmbFile f = new SmbFile("smb://10.17.15.12/Share/xml/file.xml", auth); 
     SmbFileInputStream in = new SmbFileInputStream(f); 
     byte[] b = new byte[8192]; 
     int n; 
     while((n = in.read(b)) > 0) { 
     System.out.write(b, 0, n); 
     } 
    } catch (SmbException smbe) { 
     System.err.println(smbe.getNtStatus()); 
     System.err.println(smbe.toString()); 
     System.err.println(smbe.getCause()); 
    } 
    } 
} 

La producción inicial tarda mucho en llegar y las lecturas posteriores también son muy lentas. ¿Alguna idea de cómo usarlo? Cualquier alternativa con la que pueda escribir código Java para acceder a los recursos compartidos de Windows de forma portátil también es bienvenido

Respuesta

18

Encontré en algún lugar que SmbFileInputStream no hace su propio almacenamiento en búfer y, por tanto, el motivo de ser lento. Envolver SmbFileInputStream en un BufferedInputStream resolvió el problema.

SmbFile sFile = new SmbFile(path, authentication); 

BufferedInputStream buf = new BufferedInputStream(new SmbFileInputStream(sFile)); 
+2

Sé que esta es una respuesta anterior, pero el enlace de origen parece estar obsoleto. – Vish

2

Si puede confiar en "otra cosa" para montar el recurso compartido como un directorio local, lea los archivos en el la participación compartida en Java debe ser portátil.

Incluso si esta no es una solución real, valdría la pena intentarlo para ver si obtiene una tasa de lectura más rápida. Una velocidad de lectura significativamente más rápida puede cambiar su opinión acerca de la importancia relativa de la portabilidad. Y si no obtiene una aceleración significativa, sabrá que JCIFS no tiene la culpa ...

15

En mi caso, empujar archivos a un recurso compartido de Windows a través de JCIFS era demasiado lento para ser utilizable.

La solución resultó ser la definición de la propiedad

 
-Djcifs.resolveOrder=DNS 

El default inclusion de BCAST - la transmisión de un nombre de la consulta NetBIOS a 255.255.255.255 - fue resultantes innecesariamente durante un largo retraso. (. Enlace por encima de-enmarcado de la top-level API docs)

+0

¡Este es un gran hallazgo! – Xolve

+1

Gracias! Claro pateó mi trasero por una semana ... – Glenn

+3

jcifs.Config.setProperty ("resolveOrder", "DNS"); me salvó la vida también! ¡¡Gracias!! – Exceptyon

2

Lo que noté es que JCIFS hace "algo" (afair jcifs.smb.SmbTransport.checkStatus(..)) para cada trozo se lee -. Es decir, para cada fragmento que se lee en la memoria intermedia Eso significa que el uso de un BufferedInputStream realmente podría acelerar las cosas, pero todavía existe el problema real. Sólo no ocurre tan a menudo como antes y por lo tanto tiene un menor impacto en el tiempo total ..

ayuda mucho a establecer "jcifs.util .loglevel = 3 "y eche un vistazo a lo que está realmente mal!

En mi caso tuve que configurar "jcifs.smb.client.dfs.disabled=false" al final, como "jcifs.resolveOrder=DNS" no ayudó ..

1

Incluso con las sugerencias existentes, todavía encuentro JCIFS demasiado lento para transmitir videos a través de mi red local. Parece que tiene que ver con la sobrecarga por lectura de buffer de la red, incluso la lectura en búferes de gran tamaño JCIFS tenía un tamaño de búfer limitado, que era el problema.

Si mira en https://jcifs.samba.org/src/patches/ hay un parche, LargeReadWrite.patch. Tendrá que aplicar el parche y reconstruir el código para usarlo, pero marcó una gran diferencia para mí.

+0

Excelente hallazgo :-) – Xolve

0

La solución agregada por @ Xolve0 funcionó para mí también. El problema del búfer en SmbFileInput también está presente cuando intenta escribir archivos. Usé el mismo BufferedInputStream(new SmbFileInputStream(sFile)) para hacer que la ejecución del tiempo disminuya de 90 segundos a menos de un segundo para un archivo de texto sin formato.

Una forma rápida de identificar este problema específico sería rastrear el tiempo entre la apertura de la ruta JCIFS y la escritura del archivo.

Cuestiones relacionadas