pysmb для получения дерева каталогов общего сервера smb

мне удается подключиться и получить доступ к общему серверу smb с помощью pysmb. я имел в виду чтение/запись/удаление/создание файлов/папок на/с сервера.

в большинстве случаев мне нужно прочитать файл (будь то jpg или csv и т. д.) с базы сервера на устройстве smb и имени службы (условия pysmb).

в основном я понятия не имею, что такое имя файла и имя каталога в устройствах smb. означает, что именование является динамикой.

мне интересно, это хорошая идея, чтобы сначала получить отфильтрованное дерево каталогов перед обработкой прочитанных файлов. количество файлов и каталогов неизвестно, данные за 3 месяца около 60 ТБ.

listShares(timeout=30)[source]
listPath(service_name, path, search=55, pattern='*', timeout=30)

вышеупомянутые методы собираются получить только 1 определенный уровень иерархии. то, что я хочу, это аналогичный вывод из os.walk.path().

у кого-нибудь есть опыт в идее? могу ли я получить предложения? большое тебе спасибо.


person pinky    schedule 20.10.2015    source источник


Ответы (3)


Не уверен, что это то, что вы хотите. но я работаю над подобными вещами, так что держи.

Я использую Impacket, который на самом деле использует некоторые базовые классы из pysmb. https://github.com/CoreSecurity/impacket

Я надеюсь, что ваш метод listPath возвращает вывод в текстовом формате, а не экземпляр SharedFile.

Я имею в виду, хранить ниже значения при их перечислении.

get_longname is_directory get_filesize

У меня есть метод дерева, который проходит через общий ресурс/путь и проверяет, является ли экземпляр SharedFile каталогом, и выполняет рекурсивный вызов самого себя.

def tree(self, path):    
   for x in range(0, path.count('\\')):
            print '|  ',
    print '%s' % os.path.basename(path.replace('\\', '/'))

    self.do_ls('%s\\*' % path, pretty=False) #Stores files data in listdata[]

    for file, is_directory, size in self.listdata:
            if file in ('.', '..'):
                continue
            if is_directory > 0:
                self.tree(ntpath.join(path, file))
            else:
                for x in range(0, path.count('\\')):
                    print '|  ',
                print '|-- %s (%d bytes)' % (file, size)


>>>d.tree('test')
.snapshot
|   hourly.0
|   |   dir0
|   |   |   Test051-89
|   |   |   Test051_perf3100-test_43
|   |   |   |   Test051_perf3100-test_52
|   |-- a.txt (8 bytes)
|   |-- dir0 - Shortcut.lnk (1834 bytes)
|   |-- Thumbs.db (46080 bytes)
|   |   20743
|   |   |-- file.txt (82 bytes)
|   |   |-- link.txt (82 bytes)
|   |   |   targetdir
|   |   |   |-- file2.txt (39 bytes)
|   |-- target.txt (6394368 bytes)
|   |   linkdir
|   |   |-- file2.txt (39 bytes)
person Rohit.M    schedule 21.10.2015
comment
большое тебе спасибо. ваш код хорош. Я также делюсь своей работой. пожалуйста, посмотрите, если у вас есть время. - person pinky; 26.10.2015

def smbwalk(conn, shareddevice, top = u'/'):
    dirs , nondirs = [], []

    if not isinstance(conn, SMBConnection):
        raise TypeError("SMBConnection required")


    names = conn.listPath(shareddevice, top)

    for name in names:
        if name.isDirectory:
            if name.filename not in [u'.', u'..']:
                dirs.append(name.filename)
        else:
            nondirs.append(name.filename)

    yield top, dirs, nondirs

    for name in dirs:
        new_path = os.path.join(top, name)
        for x in smbwalk(conn, shareddevice, new_path):
            yield x


conn = SMBConnection(*con_str, domain='workgroup')
assert conn.connect('10.10.10.10')
ans = smbwalk(conn, 'SHARE_FOLDER',top= '/')

это то, что я хочу, но я обнаружил, что если общие ресурсы сети слишком велики, для возврата потребуется вечность.

person pinky    schedule 26.10.2015
comment
спасибо за помощь, я приму ваш ответ. большое тебе спасибо. - person pinky; 28.10.2015

Вы рассматривали возможность использования потоков? Быстрая идея состоит в том, чтобы получить все каталоги верхнего уровня, затем использовать потоки для всех из них и использовать функцию smbwalk. Во время ходьбы по дереву он ищет объекты, поэтому это займет время. но вы увидите улучшение производительности при использовании потоков.

person Rohit.M    schedule 28.10.2015
comment
спасибо за идею. очень хорошее предложение для меня. интересно, каково максимальное количество потоков в python. это зависит от оборудования и ОС? напр. Максимальное количество потоков i7 4 core составляет 8. Думаю, я не совсем прав. - person pinky; 29.10.2015
comment
моя ситуация: 3 smb сервера. 90 ежедневных папок в каждой. 200+ папок в каждой ежедневной папке. 20+ папок в каждой из 200+ папок. 10+ папок в каждой из 20+. много почтовых индексов в 10+ папках. каждый почтовый индекс имеет как минимум 5-уровневую иерархию. мне нужно вернуть абсолютный путь к базе zip для содержимого в файле внутри zip. чтобы пользователь мог загрузить zip-файл на основе серийного номера или квитанции #. - person pinky; 29.10.2015
comment
На самом деле, это зависит как от ОС, так и от H/W. 1›200+›20+›10+›~›read›return Таким образом, вы должны прочитать содержимое файла, а затем вернуть путь, основанный на том, что вы не знаете, что именно вы ищете. Обычный список каталогов, т. е. \\server\share*, вызывает SMB2_FIND_BOTH_DIRECTORY_INFO. Который, в свою очередь, возвращает метки времени, размер ea, атрибуты, имя, eof, размер распределения, индекс, следующее смещение и длину имени. Вы можете проверить это, сократив всю эту информацию до индекса, следующего смещения и имени. Или есть ли какие-либо оптимизации только для чтения, доступные для вашего smbserver? вы можете настроить их. Они есть на всех NAS-серверах. - person Rohit.M; 28.01.2016