【问题标题】:pysmb to get directory tree of a smb share serverpysmb 获取 smb 共享服务器的目录树
【发布时间】:2015-10-20 03:11:16
【问题描述】:

我设法使用 pysmb 连接和访问 smb 共享服务器。 我的意思是从服务器读取/写入/删除/创建文件/文件夹。

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

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

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

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

上述方法只能获得层次结构的 1 个特定级别。 我想要的是来自os.walk.path() 的类似输出。

有人有想法吗?我能得到建议吗?非常感谢。

【问题讨论】:

    标签: python linux samba os.walk


    【解决方案1】:
    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= '/')
    

    这就是我想要的,但我发现如果网络共享太大,它会永远返回。

    【讨论】:

    • 感谢您的帮助,我会接受您的回答。非常感谢。
    • 非常感谢!
    【解决方案2】:

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

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

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

    我的意思是,在列出它们时存储以下值。

    get_longname is_directory 获取文件大小

    我有遍历共享/路径并检查 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)
    

    【讨论】:

    • 非常感谢。你的代码很好。我也分享了我的工作。如果你有时间,请看看。
    【解决方案3】:

    你考虑过使用线程吗?快速的想法是获取所有顶级目录,然后为所有目录使用线程并使用您的 smbwalk 函数。在 tree walk 时,它会查找对象,因此需要时间。但是您会看到使用线程的性能改进。

    【讨论】:

    • 感谢您的想法。对我很好的建议。我想知道python中的最大线程数是多少。它依赖于硬件和操作系统吗?例如。 i7 4 core max threads is 8.我相信我不太正确。
    • 我的情况:3个smb服务器。每天 90 个文件夹。每个每日文件夹中有 200 多个文件夹。 200 多个文件夹中的每个文件夹中有 20 多个文件夹。 20 多个文件夹中的每个文件夹中有 10 多个。 10 多个文件夹中有许多 zip。每个 zip 至少有 5 级层次结构。我需要根据 zip 内文件中的内容返回 zip 的绝对路径。因此用户可以根据序列号或收据号下载 zipfile。
    • 实际上,它既依赖于操作系统,也依赖于硬件。 1>200+>20+>10+>~>read>return 所以你必须读取文件的内容,然后根据“不知道你具体看什么”返回路径。普通目录列表,即 \\server\share* 调用 SMB2_FIND_BOTH_DIRECTORY_INFO。依次返回时间戳、ea 大小、属性、名称、eof、分配大小、索引、下一个偏移量和名称长度。您可能希望通过将所有这些信息减少到仅索引、下一个偏移量和名称来进行检查。或者,您的 smbserver 是否有任何只读优化?你可以调整它们。所有 NAS 服务器都有它们
    猜你喜欢
    • 1970-01-01
    • 2014-03-22
    • 2021-09-24
    • 1970-01-01
    • 2012-11-17
    • 1970-01-01
    • 2021-10-09
    • 2015-03-24
    • 2013-03-28
    相关资源
    最近更新 更多