如何强制脚本根据其目录关闭所有打开的文件?

时间:2019-01-25 10:21:14

标签: python python-3.x file psutil

是否可以仅基于打开目录关闭打开的文件?我想关闭具有特定扩展名的文件。如果不可能,我可以关闭所有打开的文件。我的代码太长了,以至于我无法以其他方式控制文件的关闭。我正在为外部用户准备应用程序,并且开发了“重置”按钮,但是由于这些文件仍处于打开状态,导致访问某些文件夹时遇到问题。

我正在使用psutil通过.py脚本获取所有打开的文件的列表。

[popenfile(path='C:\\Users\\Jan\\AppData\\Local\\Microsoft\\Windows\\Explorer\\iconcache_48.db', fd=-1),
popenfile(path='D:\\jan\\apka_update\\temp\\17-Z1-20180704_Lk7_156.000-180.000_niepelne\\intersection1B.shp', fd=-1),
popenfile(path='D:\\jan\\apka_update\\temp\\17-Z1-20180704_Lk7_156.000-180.000_niepelne\\intersection1A.dbf', fd=-1),
popenfile(path='D:\\jan\\apka_update\\temp\\17-Z1-20180704_Lk7_156.000-180.000_niepelne\\intersection1A.shp', fd=-1),
popenfile(path='C:\\Windows\\System32\\pl-PL\\explorerframe.dll.mui', fd=-1),
popenfile(path='D:\\jan\\apka_update\\temp\\17-Z1-20180704_Lk7_156.000-180.000_niepelne\\polygonSet1B.shp', fd=-1),
popenfile(path='C:\\Users\\Jan\\AppData\\Local\\Microsoft\\Windows\\Explorer\\iconcache_idx.db', fd=-1),
popenfile(path='C:\\Windows\\System32\\pl-PL\\user32.dll.mui', fd=-1),
popenfile(path='C:\\Users\\Jan\\AppData\\Local\\Microsoft\\Windows\\Explorer\\thumbcache_idx.db', fd=-1),
popenfile(path='D:\\jan\\apka_update\\temp\\17-Z1-20180704_Lk7_156.000-180.000_niepelne\\intersection1B.shx', fd=-1),
popenfile(path='D:\\jan\\apka_update\\temp\\17-Z1-20180704_Lk7_156.000-180.000_niepelne\\PolygonSet1A.dbf', fd=-1),
popenfile(path='D:\\jan\\apka_update\\temp\\17-Z1-20180704_Lk7_156.000-180.000_niepelne\\obszar_zainteresowania.dbf', fd=-1),
popenfile(path='C:\\Windows\\System32\\pl-PL\\dui70.dll.mui', fd=-1),
popenfile(path='D:\\jan\\apka_update\\temp\\17-Z1-20180704_Lk7_156.000-180.000_niepelne\\intersection1B.dbf', fd=-1),
popenfile(path='D:\\jan\\apka_update\\temp\\17-Z1-20180704_Lk7_156.000-180.000_niepelne\\polygonSet1B.dbf', fd=-1),
popenfile(path='C:\\Windows\\System32\\pl-PL\\shell32.dll.mui', fd=-1),
popenfile(path='C:\\Windows\\System32\\pl-PL\\propsys.dll.mui', fd=-1),
popenfile(path='C:\\Users\\Jan\\AppData\\Local\\Microsoft\\Windows\\Explorer\\thumbcache_96.db', fd=-1),
popenfile(path='D:\\jan\\apka_update\\temp\\17-Z1-20180704_Lk7_156.000-180.000_niepelne\\obszar_zainteresowania.shp', fd=-1),
popenfile(path='C:\\Windows\\System32\\pl-PL\\NetworkItemFactory.dll.mui', fd=-1),
popenfile(path='C:\\Windows\\System32\\pl-PL\\comdlg32.dll.mui', fd=-1),
popenfile(path='C:\\Windows\\Fonts\\StaticCache.dat', fd=-1),
popenfile(path='C:\\Users\\Jan\\AppData\\Local\\Microsoft\\Windows\\Explorer\\iconcache_256.db', fd=-1),
popenfile(path='D:\\jan\\apka_update\\temp\\17-Z1-20180704_Lk7_156.000-180.000_niepelne\\PolygonSet1A.shp', fd=-1),
popenfile(path='C:\\Windows\\System32\\pl-PL\\windows.storage.dll.mui', fd=-1),
popenfile(path='D:\\jan\\apka_update\\temp\\17-Z1-20180704_Lk7_156.000-180.000_niepelne\\intersection1A.shx', fd=-1),
popenfile(path='C:\\Windows\\System32\\pl-PL\\mpr.dll.mui', fd=-1),
popenfile(path='C:\\Windows\\System32\\pl-PL\\KernelBase.dll.mui', fd=-1),
popenfile(path='C:\\Users\\Jan\\AppData\\Local\\Microsoft\\Windows\\Explorer\\iconcache_16.db', fd=-1)]    

3 个答案:

答案 0 :(得分:0)

您可以使用内置的os.path库或不错的path.py测试目录和扩展名。

for fname in my_files:
    _, ext = os.path.splitext(fname)
    dirname = os.path.join(fname, os.pardir)

    if ext=".txt" and dirname ="my_dir":
        # close your file

或者,使用path.py:

for fname in my_files:
    fname = Path(fname)
    if fname.ext == ".txt" and fname.parent == "my_dir":
        # close your file

答案 1 :(得分:0)

  

我的代码太长了,以至于我无法以其他方式控制文件的关闭。

然后是时候停止所有操作并修复代码了。实际上,您的代码应该在完成处理后立即关闭每个文件(the with statement is your friend here),而且我很难考虑是否要保持一次打开多个文件的任何原因。

在所有情况下:需要关闭文件的引用(句号)。如果您打开文件,请不要关闭它并丢弃对该文件的引用,那么...太糟糕了。

好吧,最终可能会有一个非常丑陋的解决方法,那就是将所有open()调用替换为您自己的版本,该版本将打开的文件存储在某些全局列表中。但实际上,那只会使您的代码更糟,所以做对的事情:修复代码以在正确的位置正确关闭文件。

答案 2 :(得分:0)

类似的事情应该可以解决问题。

import psutil

## Close open processes matching the path.
pathToClear = "{PATH GOES HERE}"

print(f"...Searching for active processes matching path: '{pathToClear}'")
for proc in psutil.process_iter(['name', 'open_files']):
    for file in proc.info['open_files'] or []:
        if pathToClear in file.path:
            print(f"Found process potentiall process potentially locking path. Killing: '{proc.info['name']}'")
            print("%-5s %-10s %s" % (proc.pid, proc.info['name'][:10], file.path))
            proc.kill()

print("Completed!")

参考: