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
路径打开与文件本身写入之间的时间。