JCIFS:文件检索太慢而无法使用
Posted
技术标签:
【中文标题】JCIFS:文件检索太慢而无法使用【英文标题】:JCIFS: file retrieval is too slow to be usable 【发布时间】:2012-05-19 00:07:18 【问题描述】:我只是在测试 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 共享的任何替代方法
【问题讨论】:
【参考方案1】:如果您可以依靠“其他东西”将共享挂载为本地目录,那么在 Java 中读取挂载共享中的文件应该是可移植的。
即使这不是一个真正的解决方案,也值得尝试一下,看看您是否能获得更快的读取速度。明显更快的读取速度可能会改变您对便携性相对重要性的看法。如果你没有得到显着的加速,那么你就会知道 JCIFS 不是罪魁祸首……
【讨论】:
【参考方案2】:我在某处发现 SmbFileInputStream 不做自己的缓冲,因此是慢的原因。将 SmbFileInputStream 封装在 BufferedInputStream 中解决了这个问题。
SmbFile sFile = new SmbFile(path, authentication);
BufferedInputStream buf = new BufferedInputStream(new SmbFileInputStream(sFile));
【讨论】:
【参考方案3】:在我自己的情况下,通过 JCIFS 将文件推送到 Windows 共享太慢而无法使用。
解决方案原来是定义属性
-Djcifs.resolveOrder=DNSBCAST 的default inclusion——将 NetBIOS 名称查询广播到 255.255.255.255——不必要地导致了长时间的延迟。 (以上链接来自top-level API docs。)
【讨论】:
这是一个很棒的发现! jcifs.Config.setProperty("resolveOrder", "DNS");也救了我的命!谢谢!! @Exceptyon - 也许应该是 "jcifs.Config.setProperty("jcifs.resolveOrder", "DNS");" (对我来说效果更好)【参考方案4】:我注意到的是,jCIFS 做了“一些事情”(对于它读取的每个块,jcifs.smb.SmbTransport.checkStatus(..))
公平 - 即对于读入缓冲区的每个块。这意味着使用 BufferedInputStream
可能真的会加快速度,但是真正的问题仍然存在。它只是不像以前那样经常发生,因此对整体时间的影响较小..
设置“jcifs.util.loglevel=3”有很大帮助,看看到底出了什么问题!
就我而言,最后我不得不设置"jcifs.smb.client.dfs.disabled=false"
,因为"jcifs.resolveOrder=DNS"
没有帮助..
【讨论】:
【参考方案5】:即使有现有的建议,我仍然发现 JCIFS 速度太慢,无法通过我的本地网络传输视频。这似乎与从网络读取每个缓冲区的开销有关,即使读取到大缓冲区 JCIFS 本身也有一个有限的缓冲区大小,这就是问题所在。
如果您查看https://jcifs.samba.org/src/patches/,就会看到一个补丁,LargeReadWrite.patch。您需要应用补丁并重建代码才能使用它,但这对我来说有很大的不同。
【讨论】:
很好的发现:-)【参考方案6】:@Xolve0 添加的解决方案也对我有用。尝试写入文件时,SmbFileInput
中的缓冲区问题也存在。我使用相同的BufferedInputStream(new SmbFileInputStream(sFile))
使纯文本文件的执行时间从 90 秒减少到不到一秒。
识别此特定问题的一种快速方法是跟踪打开JCIFS
路径和写入文件本身之间的时间。
【讨论】:
您是否尝试过使用非默认缓冲区大小?默认似乎是DEFAULT_BUFFER_SIZE = 8192
,我想如果这是两倍或三倍,它不会有太大变化......【参考方案7】:
我知道这是一个老问题,但对于尝试过其他解决方案无济于事的其他人来说:
就我而言,我能够跟踪 jcifs 对SecureRandom
的大量使用的减速,如果/dev/random
报告熵不足,则会阻塞。
安装rng-tools
并配置和启用rngd
使性能达到可接受的水平。
您可以使用以下命令check the available entropy(至少在 RHEL 上):
cat /proc/sys/kernel/random/entropy_avail
【讨论】:
以上是关于JCIFS:文件检索太慢而无法使用的主要内容,如果未能解决你的问题,请参考以下文章