Подтвердить что ты не робот

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, также приветствуются

4b9b3361

Ответ 1

Я где-то нашел, что SmbFileInputStream не выполняет свою собственную буферизацию и, следовательно, является причиной медленной работы. Обертка SmbFileInputStream в BufferedInputStream решила проблему.

 SmbFile sFile = new SmbFile(path, authentication);

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

Ответ 2

В моем случае, нажатие файлов на общий ресурс Windows через JCIFS было слишком медленным, чтобы его можно было использовать.

Решение оказалось определяющим свойством

-Djcifs.resolveOrder=DNS

включение по умолчанию BCAST - трансляция запроса имени NetBIOS на 255.255.255.255 - было бесполезно, что привело к длительной задержке. (Ссылка выше дефрагментирована из документов верхнего уровня API.)

Ответ 3

Если вы можете полагаться на "что-то еще", чтобы монтировать общий ресурс как локальный каталог для вас, то чтение файлов на смонтированном ресурсе в Java должно быть переносимым.

Даже если это не настоящее решение, было бы полезно попробовать это, если вы получите более быструю скорость чтения. Значительно более быстрая скорость чтения может изменить ваше мнение относительно относительной важности переносимости. И если вы не получите значительное ускорение, тогда вы узнаете, что JCIFS не виноват...

Ответ 4

Я заметил, что jCIFS делает "что-то" (afair 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 и записью самого файла.