gpt4 book ai didi

python - 如何使用 Python 和 ctypes 在 Windows 上读取或写入 as h r i 文件属性?

转载 作者:可可西里 更新时间:2023-11-01 10:33:29 25 4
gpt4 key购买 nike

备案:

  • a 表示“可归档”
  • s 表示“系统”
  • h 表示“隐藏”
  • r 表示“只读”
  • i 表示“可索引”

我当前从 Python 脚本读取/写入这些属性的解决方案是使用 subprocess 调用 attrib模块。

Python代码:

import os, subprocess

def attrib(path, a=None, s=None, h=None, r=None, i=None):
attrs=[]
if r==True: attrs.append('+R')
elif r==False: attrs.append('-R')
if a==True: attrs.append('+A')
elif a==False: attrs.append('-A')
if s==True: attrs.append('+S')
elif s==False: attrs.append('-S')
if h==True: attrs.append('+H')
elif h==False: attrs.append('-H')
if i==True: attrs.append('+I')
elif i==False: attrs.append('-I')

if attrs: # write attributes
cmd = attrs
cmd.insert(0,'attrib')
cmd.append(path)
cmd.append('/L')
return subprocess.call(cmd, shell=False)

else: # just read attributes
output = subprocess.check_output(
['attrib', path, '/L'],
shell=False, universal_newlines=True
)[:9]
attrs = {'A':False, 'S':False, 'H':False, 'R':False, 'I':False}
for char in output:
if char in attrs:
attrs[char] = True
return attrs

path = 'C:\\test\\'
for thing in os.listdir(path):
print(thing, str(attrib(os.path.join(path,thing))))

输出:

archivable.txt {'A': True, 'I': False, 'S': False, 'H': False, 'R': False}
hidden.txt {'A': True, 'I': False, 'S': False, 'H': True, 'R': False}
normal.txt {'A': True, 'I': False, 'S': False, 'H': False, 'R': False}
readonly.txt {'A': True, 'I': False, 'S': False, 'H': False, 'R': True}
system.txt {'A': True, 'I': False, 'S': True, 'H': False, 'R': False}

但是当目录包含许多条目时(每个条目一个子进程调用),这执行起来很慢。

我不想使用 win32api模块,因为我不想要第三方模块依赖项。我也很好奇如何使用 ctypes 来做到这一点.

我偶然发现了 Hide Folders/ File with Python [closed] , Set "hide" attribute on folders in windows OS?Python: Windows System File ,但这对我来说并不清楚。特别是我不明白这些 0x4 es 0x02 es 是什么。你能解释一下吗?能给个具体的代码例子吗?

最佳答案

在 eriksuns 对我的问题的评论的帮助下,我解决了它。这是我的问题的代码,但现在使用 ctypes , statos.scandir .它需要 Python 3.5+。写入速度快约 50 倍,读取速度快约 900 倍。

Python代码:

from os import scandir, stat
from stat import (
FILE_ATTRIBUTE_ARCHIVE as A,
FILE_ATTRIBUTE_SYSTEM as S,
FILE_ATTRIBUTE_HIDDEN as H,
FILE_ATTRIBUTE_READONLY as R,
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED as I
)
from ctypes import WinDLL, WinError, get_last_error

def read_or_write_attribs(
# https://docs.python.org/3/library/ctypes.html#ctypes.WinDLL
kernel32,

# https://docs.python.org/3/library/os.html#os.DirEntry
entry,

# archive, system, hidden, readonly, indexed
a=None, s=None, h=None, r=None, i=None,

# Set to True when you call this function more than once on the same entry.
update=False
):

# Get the file attributes as an integer.
if not update:
# Fast because we access the stats from the entry
attrs = entry.stat(follow_symlinks=False).st_file_attributes
else:
# A bit slower because we re-read the stats from the file path.
# Notice that this will raise a "WinError: Access denied" on some entries,
# for example C:\System Volume Information\
attrs = stat(entry.path, follow_symlinks=False).st_file_attributes

# Construct the new attributes
newattrs = attrs
def setattrib(attr, value):
nonlocal newattrs
# Use '{0:032b}'.format(number) to understand what this does.
if value is True: newattrs = newattrs | attr
elif value is False: newattrs = newattrs & ~attr
setattrib(A, a)
setattrib(S, s)
setattrib(H, h)
setattrib(R, r)

# Because this attribute is True when the file is _not_ indexed
setattrib(I, i if i is None else not i)

# Optional add more attributes here.
# See https://docs.python.org/3/library/stat.html#stat.FILE_ATTRIBUTE_ARCHIVE

# Write the new attributes if they changed
if newattrs != attrs:
if not kernel32.SetFileAttributesW(entry.path, newattrs):
raise WinError(get_last_error())

# Return an info tuple consisting of bools
return (
bool(newattrs & A),
bool(newattrs & S),
bool(newattrs & H),
bool(newattrs & R),

# Because this attribute is true when the file is _not_ indexed
not bool(newattrs & I)
)

# Test it
if __name__ == '__main__':

# Contains 'myfile.txt' with default attributes
path = 'C:\\test\\'

kernel32 = WinDLL('kernel32', use_last_error=True)

# Tool for prettyprinting to the console
template = ' {} (a={}, s={}, h={}, r={}, i={})'
def pp (attribs):
print(template.format(
entry.path,
*attribs
))

print('\nJust read the attributes (that is quick):')
for entry in scandir(path):
pp(read_or_write_attribs(kernel32, entry))

print("\nSet 'readonly' to true (that is quick):")
for entry in scandir(path):
pp(read_or_write_attribs(kernel32, entry, r=True))

print(
"\nSet 'system' to true, then set 'system' to false, "
"then set 'readonly' to false (that is slow):"
)
for entry in scandir(path):
pp(read_or_write_attribs(
kernel32, entry,
s=True
))
pp(read_or_write_attribs(
kernel32, entry,
s=False,
update=True
))
pp(read_or_write_attribs(
kernel32, entry,
r=False,
update=True
))

输出:

C:\>ashri_example.py

Just read the attributes (that is quick):
C:\test\myfile.txt (a=True, s=False, h=False, r=False, i=True)

Set 'readonly' to true (that is quick):
C:\test\myfile.txt (a=True, s=False, h=False, r=True, i=True)

Set 'system' to true, then set 'system' to false, then set 'readonly' to false (slow):
C:\test\myfile.txt (a=True, s=True, h=False, r=True, i=True)
C:\test\myfile.txt (a=True, s=False, h=False, r=True, i=True)
C:\test\myfile.txt (a=True, s=False, h=False, r=False, i=True)

C:\>

关于python - 如何使用 Python 和 ctypes 在 Windows 上读取或写入 as h r i 文件属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40367961/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com