pysmb 获取 smb 共享服务器的目录树

pysmb to get directory tree of a smb share server

我设法使用 pysmb 连接并访问 smb 共享服务器。 我的意思是 read/write/delete/create files/folders to/from 服务器。

大部分时间我需要根据 smb 设备和服务名称(pysmb 术语)从服务器读取文件(无论是 jpg 还是 csv 等)。

基本上我不知道 smb 设备中的文件名和目录名是什么。意思是命名是动态的。

我想知道在处理读取的文件之前先获取过滤后的目录树是否是个好主意。文件和目录的数量未知,大约 3 个月的数据约为 60TB。

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

上述方法只能获取层次结构的 1 个特定级别。 我想要的是 os.walk.path().

的类似输出

有人有idea经验吗?我可以得到建议吗?非常感谢。

不确定这是否是您想要的。但我正在研究类似的东西所以给你。

我使用 Impacket,它实际上使用了来自 pysmb 的一些基础 类。 https://github.com/CoreSecurity/impacket

我希望您的 listPath 方法返回文本格式的输出,而不是 SharedFile 实例。

我的意思是,在列出值时存储低于值。

get_longname is_directory get_filesize

我有遍历 share/path 并检查 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)
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= '/')

这就是我想要的,但我发现如果网络共享太大,return 就需要很长时间。

您考虑过使用线程吗?快速的想法是获取所有顶级目录,然后对所有这些目录使用线程并使用您的 smbwalk 函数。树行走时,它会查找对象,因此需要时间。但是你会看到使用线程的性能提升。