简体   繁体   English

如何从 Python fcache 中迭代和删除某些文件?

[英]How to iterate through and delete certain files from Python fcache?

In my PyQt5 app, I've been using fache ( https://pypi.org/project/fcache/ ) to cache lots of small files to the user's temp folder for speed.在我的 PyQt5 应用程序中,我一直在使用 fache ( https://pypi.org/project/fcache/ ) 将大量小文件缓存到用户的临时文件夹中以提高速度。 It's working well for caching, but now I need to be able to iterate through the cached files and selectively delete files that are no longer needed.它适用于缓存,但现在我需要能够遍历缓存的文件并有选择地删除不再需要的文件。

However when I try to iterate through the FileCache object, I'm getting an error.但是,当我尝试遍历 FileCache 对象时,出现错误。

thisCache is the name of my cache, and if I print(thisCache) I get: which is fine. thisCache是我的缓存的名称,如果我print(thisCache)我得到: 这很好。

Then if I do print(thisCache.keys()) I get KeysView(<fcache.cache.FileCache object at 0x000001F7BA0F2848>) , which seems correct (I think?).然后,如果我执行print(thisCache.keys())我得到KeysView(<fcache.cache.FileCache object at 0x000001F7BA0F2848>) ,这似乎是正确的(我认为?)。 Similarly, printing .values() gives me a ValuesView.同样,打印 .values() 给了我一个 ValuesView。

Then if I do print(len(thisCache.keys()) I get: 1903 , showing that there are 1903 files in there, which is probably correct. But here's where I get stuck.然后,如果我执行print(len(thisCache.keys())我得到: 1903 ,表明那里有 1903 个文件,这可能是正确的。但这是我卡住的地方。

If I try to iterate through the KeysView in any way, I get an error.如果我尝试以任何方式遍历 KeysView,则会出现错误。 Each of the following attempts: for f in thisCache.values(): for f in thisCache.keys(): always throws an error: Process finished with exit code -1073740791 (0xC0000409)以下每次尝试: for f in thisCache.values(): for f in thisCache.keys(): always throws an error: Process finished with exit code -1073740791 (0xC0000409)

I'm fairly new to Python, so am I just misunderstanding how I'm supposed to iterate through this list?我对 Python 还很陌生,所以我只是误解了我应该如何遍历这个列表吗? Or is there a bug or gotcha here that I need to work around?或者这里有我需要解决的错误或问题吗?

Thanks谢谢

::::::::: EDIT :::::::: ::::::::: 编辑 ::::::::

After a bit of a delay, here's a reproducile (but not especially minimal or quality) bit of example code.经过一段时间的延迟,这是一个可重现的(但不是特别少或质量)的示例代码。

import random
import string
from fcache.cache import FileCache
from shutil import copyfile

def random_string(stringLength=10):
    letters = string.ascii_lowercase
    return ''.join(random.choice(letters) for i in range(stringLength))

cacheName = "TestCache"
cache = FileCache(cacheName)

sourceFile = "C:\\TestFile.mov"
targetCount = 50

# copy the file 50 times:
for w in range(1, targetCount+1):
    fileName = random_string(50) + ".mov"
    targetPath = cache.cache_dir + "\\" + fileName
    print("Copying file ", w)
    copyfile(sourceFile, targetPath)
    cache[str(w)] = targetPath
print("Cached", targetCount, "items.")

print("Syncing cache...")
cache.sync()

# iterate through the cache:
print("Item keys:", cache.keys())
for key in cache.keys():
    v = cache[key]
    print(key, v)

print("Cache read.")

There is one dependency, which is having a file called "C:\\TestFile.mov" on your system, but the path isn't important so this can be pointed to any file.有一个依赖项,它在您的系统上有一个名为“C:\\TestFile.mov”的文件,但路径并不重要,因此它可以指向任何文件。 I've tested with other file formats, with the same result.我用其他文件格式测试过,结果相同。

The error that is thrown is:抛出的错误是:

Traceback (most recent call last): File "C:\\Users\\stuart.bruce\\AppData\\Local\\Programs\\Python\\Python37\\lib\\encodings\\hex_codec.py", line 19, in hex_decode return (binascii.a2b_hex(input), len(input)) binascii.Error: Non-hexadecimal digit found回溯(最近一次调用):文件“C:\\Users\\stuart.bruce\\AppData\\Local\\Programs\\Python\\Python37\\lib\\encodings\\hex_codec.py”,第 19 行,在 hex_decode 返回(binascii.a2b_hex(输入), len(input)) binascii.Error: 发现非十六进制数字

The above exception was the direct cause of the following exception:上述异常是以下异常的直接原因:

Traceback (most recent call last):
  File 
"C:\Users\stuart.bruce\AppData\Local\Programs\Python\Python37\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "C:\Users\stuart.bruce\AppData\Local\Programs\Python\Python37\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Users\stuart.bruce\PycharmProjects\testproject\test_code.py", line 32, in <module>
    for key in cache.keys():
  File "C:\Users\stuart.bruce\AppData\Local\Programs\Python\Python37\lib\_collections_abc.py", line 720, in __iter__
    yield from self._mapping
  File "C:\Users\stuart.bruce\AppData\Local\Programs\Python\Python37\lib\site-packages\fcache\cache.py", line 297, in __iter__
    yield self._decode_key(key)
  File "C:\Users\stuart.bruce\AppData\Local\Programs\Python\Python37\lib\site-packages\fcache\cache.py", line 211, in _decode_key
    bkey = codecs.decode(key.encode(self._keyencoding), 'hex_codec')
binascii.Error: decoding with 'hex_codec' codec failed (Error: Non-hexadecimal digit found)

Line 32 of test_code.py (as mentioned in the error) is the line for key in cache.keys(): , so this is where it seems a non-hexidecimal character is being found. test_code.py 的第 32 行(如错误中所述)是for key in cache.keys():的行,因此这似乎是发现非十六进制字符的地方。 But firstly I'm not sure why, and secondly I don't know how to get around it?但首先我不知道为什么,其次我不知道如何解决它?

(PS. Please note that if you run this code, you'll end up with 50 copies of your chosen file in your temp folder, and nothing will tidy it up automatically!) (PS。请注意,如果您运行此代码,您最终会在临时文件夹中获得所选文件的 50 个副本,并且不会自动整理!)

After reading the sources of fcache, it seems that the cache_dir should only be used by fcache itself, as it reads all its files to find previously created cache data.在阅读了 fcache 的来源之后,似乎cache_dir应该只由 fcache 本身使用,因为它读取所有文件以查找以前创建的缓存数据。

The program (or, better, the module) crashes because you created the other files in that directory, and it cannot deal with them.程序(或者更好的是模块)崩溃,因为您在该目录中创建了其他文件,并且无法处理它们。

The solution is to use another directory to store those files.解决方案是使用另一个目录来存储这些文件。

import os

# ...

data_dir = os.path.join(os.path.dirname(cache.cache_dir), 'data')
if not os.path.exists(data_dir):
    os.mkdir(data_dir)
for w in range(1, targetCount+1):
    fileName = random_string(50) + ".mov"
    targetPath = os.path.join(data_dir, fileName)
    copyfile(sourceFile, targetPath)
    cache[str(w)] = targetPath

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM