简体   繁体   English

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

[英]JCIFS: file retrieval is too slow to be usable

I was just testing JCIFS for accessing Windows shares. 我只是在测试JCIFS以访问Windows共享。 It is very slow to the point of being completely unusable. 完全无法使用它是非常缓慢的。

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

It takes very long time for initial output to come and subsequent reads are also very slow. 初始输出需要很长时间,后续读取也很慢。 Any ideas how to use it? 任何想法如何使用它? Any alternatives by which I can write Java code to access the Windows shares in a portable way are also welcome 我也可以使用任何替代方法编写Java代码以便携式方式访问Windows共享

I found somewhere that SmbFileInputStream doesn't do its own buffering and hence the reason for being slow. 我发现某处SmbFileInputStream没有自己的缓冲,因此是缓慢的原因。 Wrapping SmbFileInputStream in a BufferedInputStream solved the problem. 在BufferedInputStream中包装SmbFileInputStream解决了这个问题。

 SmbFile sFile = new SmbFile(path, authentication);

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

In my own case, pushing files TO a Windows share via JCIFS was too slow to be usable. 在我自己的情况下,通过JCIFS将文件推送到Windows共享太慢而无法使用。

The solution turned out to be defining the property 解决方案最终定义了该属性

-Djcifs.resolveOrder=DNS

The default inclusion of BCAST -- broadcasting a NetBIOS name query to 255.255.255.255 -- was needlessly resulting in a lengthy delay. 默认包含 BCAST - 将NetBIOS名称查询广播到255.255.255.255 - 不必要地导致延迟很长时间。 (Link above de-framed from the top-level API docs .) (上面的链接从顶级API文档中删除 。)

What I noticed is that jCIFS does "something" (afair jcifs.smb.SmbTransport.checkStatus(..)) for every chunk it reads - ie for each chunk that is read into the buffer. 我注意到jCIFS为它读取的每个块执行“某事”(afair jcifs.smb.SmbTransport.checkStatus(..)) - 即对于读入缓冲区的每个块。 That means using a BufferedInputStream might really speed things up, but the real problem still exists. 这意味着使用BufferedInputStream可能会加快速度,但真正的问题仍然存在。 It only doesn't occur as often as before and therefore has a lower impact on the overall time .. 它不会像以前那样频繁发生,因此对整体时间的影响较小。

It helps a lot to set " jcifs.util.loglevel=3 " and have a look what's really wrong! 设置“ jcifs.util.loglevel = 3 ”有很多帮助,看看有什么问题!

In my case I had to set "jcifs.smb.client.dfs.disabled=false" in the end, as "jcifs.resolveOrder=DNS" didn't help.. 在我的情况下,我必须在最后设置"jcifs.smb.client.dfs.disabled=false" ,因为"jcifs.resolveOrder=DNS"没有帮助..

If you can rely on "something else" to mount the share as a local directory for you, then reading files in the mounted share in Java should be portable. 如果您可以依赖“其他东西”将共享作为本地目录挂载,那么在Java中读取已挂载共享中的文件应该是可移植的。

Even if this is not a real solution, it would be worth trying this to see if you get a faster read rate. 即使这不是一个真正的解决方案,也值得尝试一下,看看你是否获得更快的读取速率。 A significantly faster read rate might change your mind about the relative importance of portability. 读取速度显着提高可能会改变您对可移植性相对重要性的看法。 And if you don't get a significant speedup, then you'll know that JCIFS is not to blame ... 如果你没有获得显着的加速,那么你就会知道JCIFS不应该受到指责......

Even with the existing suggestions I still found JCIFS too slow to stream videos over my local network. 即使有了现有的建议,我仍然发现JCIFS在本地网络上传输视频的速度太慢。 It seems to be do with the overhead per buffer read from the network, even reading into large buffers JCIFS itself had a limited buffer size which was the problem. 这似乎与从网络读取的每个缓冲区的开销有关,甚至读入大缓冲区JCIFS本身具有有限的缓冲区大小,这是问题。

If you look in https://jcifs.samba.org/src/patches/ there's a patch, LargeReadWrite.patch. 如果你查看https://jcifs.samba.org/src/patches/ ,那就有一个补丁,LargeReadWrite.patch。 You'll need to apply the patch and rebuild the code to use it, but it made a big difference for me. 你需要应用补丁并重建代码才能使用它,但它对我来说有很大的不同。

The solution added by @Xolve0 worked for me as well. @ Xolve0添加的解决方案也适用于我。 The buffer issue in the SmbFileInput is also present when trying to write files. 尝试写入文件时, SmbFileInput的缓冲区问题也会出现。 I used the same BufferedInputStream(new SmbFileInputStream(sFile)) to make the time execution decrease from 90secs to less than a second for a plain text file. 我使用相同的BufferedInputStream(new SmbFileInputStream(sFile))来使纯文本文件的时间执行从90秒减少到不到1秒。

A quick way to identify this specific issue would be to track the time between the opening of the JCIFS path and the write of the file itself. 识别此特定问题的快速方法是跟踪JCIFS路径打开与文件本身写入之间的时间。

I know this is an old question, but for anyone else who has tried the other solutions to no avail: 我知道这是一个老问题,但对于其他尝试过其他解决方案无效的人来说:

In my case, I was able to track the slowdown to jcifs' heavy use of SecureRandom , which blocks if /dev/random reports insufficient entropy. 在我的例子中,我能够跟踪jcifs 大量使用SecureRandom的速度减慢,如果/dev/random报告熵不足,则会阻止它们。

Installing rng-tools and configuring and enabling rngd brought performance up to acceptable levels. 安装rng-tools并配置和启用rngd将性能提升到可接受的水平。

You can check the available entropy (on RHEL at least) with the following command: 您可以使用以下命令检查可用的熵 (至少在RHEL上):

cat /proc/sys/kernel/random/entropy_avail

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM