JCIFS:文件检索太慢而无法使用

我只是测试JCIFS来访问Windows共享。 完全无法使用它是非常缓慢的。

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()); } } } 

初始输出需要很长时间才能到来,后续读取也非常慢。 任何想法如何使用它? 我也可以使用任何替代方法编写Java代码以便携式方式访问Windows共享

我发现某处SmbFileInputStream没有自己的缓冲,因此是缓慢的原因。 在BufferedInputStream中包装SmbFileInputStream解决了这个问题。

  SmbFile sFile = new SmbFile(path, authentication); BufferedInputStream buf = new BufferedInputStream(new SmbFileInputStream(sFile)); 

在我自己的情况下,通过JCIFS将文件推送到Windows共享太慢而无法使用。

解决方案最终定义了该属性

 -Djcifs.resolveOrder = DNS

默认包含 BCAST – 将NetBIOS名称查询广播到255.255.255.255 – 不必要地导致延迟很长时间。 (上面的链接从顶级API文档中删除 。)

如果您可以依赖“其他东西”将共享作为本地目录挂载,那么在Java中读取已挂载共享中的文件应该是可移植的。

即使这不是一个真正的解决方案,也值得尝试一下,看看你是否获得更快的读取速率。 读取速度显着提高可能会改变您对可移植性相对重要性的看法。 如果你没有获得显着的加速,那么你就会知道JCIFS不应该受到责备……

我注意到jCIFS为它读取的每个块执行“某事”(afair jcifs.smb.SmbTransport.checkStatus(..)) – 即对于读入缓冲区的每个块。 这意味着使用BufferedInputStream可能会加快速度,但真正的问题仍然存在。 它不会像以前那样频繁发生,因此对整体时间的影响较小。

设置“ jcifs.util.loglevel = 3 ”有很多帮助,看看有什么问题!

在我的情况下,我不得不设置"jcifs.smb.client.dfs.disabled=false" ,因为"jcifs.resolveOrder=DNS"没有帮助..

即使有了现有的建议,我仍然发现JCIFS太慢,无法通过本地网络传输video。 这似乎与从网络读取的每个缓冲区的开销有关,甚至读入大缓冲区JCIFS本身具有有限的缓冲区大小,这是问题。

如果你查看https://jcifs.samba.org/src/patches/ ,那就有一个补丁,LargeReadWrite.patch。 你需要应用补丁并重建代码才能使用它,但它对我来说有很大的不同。

@ Xolve0添加的解决方案也适用于我。 尝试写入文件时, SmbFileInput的缓冲区问题也会出现。 我使用相同的BufferedInputStream(new SmbFileInputStream(sFile))来使纯文本文件的执行时间从90秒减少到不到1秒。

识别此特定问题的快速方法是跟踪JCIFS路径打开与文件本身写入之间的时间。