使用 Python 更快地获取 Windows 文件的所有者

问题描述

长话短说:我正在制作一个数据库,其中包含我们公司曾经做过的所有报价。照顾特定的文件扩展名:*.prc 我要检索的信息之一是文件的所有者。 我正在使用以下代码(仅显示其中的一部分):

import os,time,win32security,subprocess
from threading import Thread
from time import time

def GET_THE_OWNER(FILENAME):
    open (FILENAME,"r").close ()
    sd = win32security.GetFileSecurity (FILENAME,win32security.OWNER_Security_informatION)
    owner_sid = sd.GetSecurityDescriptorOwner ()
    name,domain,type = win32security.LookupAccountSid (None,owner_sid)
    return name

starttime = time()

path = "C:/Users/cbabycv/Documents/Python/0. Quotations/Example"
for root,dirs,files in os.walk(path):
    for file in files:
        if (file.endswith(".prc")):
            #getting data from the file information
            Filename = os.path.join(root,file)
            try:
                Owner = GET_THE_OWNER(Filename)
            except:
                Owner = "Could not get the owner."
            print(Owner)
endtime = time()
print (Owner)
print(endtime-starttime," sec")

这个过程很慢(尤其是当你必须阅读大约 100.000 个文件时)。我想知道是否有另一种方法可以使其更快? 请注意,我要求的是 Windows 操作系统而不是其他所有东西(在这种情况下我不能使用 os.stat() - 根本不适用于 Windows) 我尝试过这里描述的另一种方式:how to find the owner of a file or directory in python 由 Paal Pedersen 提供,但它比使用 windows Api 还要慢

我正在使用 os.walk() 来查找服务器上的文件。我没有文件的确切位置,它们可以在任何文件夹中(所以我只是查看所有文件夹/子文件夹中的每个文件,看看它是否是 *.prc 文件)。一个建议的多处理 - 非常感谢 :) 我会尝试优化整个代码,但我的问题仍然有效 - 是否有更快/更好的方法在 Windows 操作系统中找到文件的所有者?

@theCreator 建议使用powershell。已经试过了。这是大约。慢 14 倍...

import os,subprocess
from pathlib import Path
from time import time

starttime = time()
def GET_THE_OWNER(cmd):
    startupinfo = subprocess.STARTUPINFO()
    startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
    completed = subprocess.run(["powershell.exe","-Command","Get-Acl ",cmd," | Select-Object Owner"],capture_output=True,startupinfo=startupinfo)
    return completed

path = Path('C:/Users/cbabycv/Documents/Python/0. Quotations/Example')
for root,file)
            Filename = "\"" + Filename +"\""
            Owner = GET_THE_OWNER(Filename)
            if Owner.returncode != 0:
                print("An error occured: %s",Owner.stderr)
            else:
                print(Owner.stdout)

endtime = time()
print(endtime-starttime," sec")

解决方法

试试这个,它会返回一个目录和子目录中所有所有者的列表。

import subprocess

mydirPath = "C:\pathTo\SomeStuff\\"
name = subprocess.call(["C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\powershell.exe","Get-ChildItem "+ mydirPath +" -Force -Recurse | select @{Name=\"Owner\";Expression={(Get-ACL $_.Fullname).Owner}}" 
,

在这种情况下通过分析器运行代码很有用:

> python3 -m cProfile -s cumtime owners.py
1.251999855041504  sec
         163705 function calls (158824 primitive calls) in 1.263 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      5/1    0.000    0.000    1.263    1.263 {built-in method builtins.exec}
        1    0.019    0.019    1.263    1.263 owners.py:1(<module>)
     4999    0.024    0.000    1.058    0.000 owners.py:6(GET_THE_OWNER)
     4999    0.423    0.000    0.423    0.000 {built-in method win32security.LookupAccountSid}
     4999    0.264    0.000    0.280    0.000 {built-in method io.open}
     4999    0.262    0.000    0.262    0.000 {built-in method win32security.GetFileSecurity}
 5778/938    0.011    0.000    0.130    0.000 os.py:280(walk)
...

这里有一些无法帮助,但可以帮助调用 LookupAccountSid 和 io.open。 SID 不会改变,毫无疑问,与文件列表相比,您需要使用的 SID 列表相当小。我实际上不确定您为什么要打开和关闭文件,但仅此一项就需要花费大量时间:

_owner_sid_cache = {}
def GET_THE_OWNER(FILENAME):
    # open (FILENAME,"r").close ()
    sd = win32security.GetFileSecurity (FILENAME,win32security.OWNER_SECURITY_INFORMATION)
    owner_sid = sd.GetSecurityDescriptorOwner ()
    if str(owner_sid) not in _owner_sid_cache:
        name,_domain,_type = win32security.LookupAccountSid (None,owner_sid)
        _owner_sid_cache[str(owner_sid)] = name
    return _owner_sid_cache[str(owner_sid)]

在使用此版本的函数和将数据输出到文件而不是相对较慢的控制台之间,时间从 252 秒减少到 5 秒,在我本地机器上有 60,000 个文件的测试文件夹中。

>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...