Python NamedTeoraryFile - ValueError при чтении
У меня возникла проблема с записью в NamedTeoraryFile на Python и последующим чтением. Функция загружает файл через tftpy во временный файл, читает его, хэширует содержимое, а затем сравнивает хэш-дайджест с исходным файлом. Рассматриваемая функция ниже:
def verify_upload(self, image, destination):
# create a tftp client
client = TftpClient(ip, 69, localip=self.binding_ip)
# generate a temp file to hold the download info
if not os.path.exists("temp"):
os.makedirs("temp")
with NamedTemporaryFile(dir="temp") as tempfile, open(image, 'r') as original:
try:
# attempt to download the target image
client.download(destination, tempfile, timeout=self.download_timeout)
except TftpTimeout:
raise RuntimeError("Could not download {0} from {1} for verification".format(destination, self.target_ip))
# hash the original file and the downloaded version
original_digest = hashlib.sha256(original.read()).hexdigest()
uploaded_digest = hashlib.sha256(tempfile.read()).hexdigest()
if self.verbose:
print "Original SHA-256: {0}\nUploaded SHA-256: {1}".format(original_digest, uploaded_digest)
# return the hash comparison
return original_digest == uploaded_digest
Проблема в том, что каждый раз, когда я пытаюсь выполнить строку uploaded_digest = hashlib.sha256(tempfile.read()).hexdigest()
ошибки приложения с ValueError - I/O Operation on a closed file
, Так как with
блок не завершен, я изо всех сил пытаюсь понять, почему временный файл будет закрыт. Единственная возможность, о которой я могу думать, это то, что tftpy закрывает файл после загрузки, но я не могу найти никакой точки в источнике tftpy, где это могло бы произойти. Обратите внимание, я также попытался вставить строку tempfile.seek(0)
для того, чтобы вернуть файл в надлежащее состояние для чтения, однако это также дает мне ValueError
,
Возможно ли закрытие файла с помощью tftpy? Я прочитал, что, возможно, есть ошибка в NamedTeoraryFile, вызывающая эту проблему? Почему файл закрыт перед ссылкой, определенной with
блок выходит за рамки?
1 ответ
TFTPy закрывает файл. Когда вы смотрели на источник, вы пропустили следующий путь кода:
class TftpClient(TftpSession):
...
def download(self, filename, output, packethook=None, timeout=SOCK_TIMEOUT):
...
self.context = TftpContextClientDownload(self.host,
self.iport,
filename,
output,
self.options,
packethook,
timeout,
localip = self.localip)
self.context.start()
# Download happens here
self.context.end() # <--
TftpClient.download
звонки TftpContextClientDownload.end
:
class TftpContextClientDownload(TftpContext):
...
def end(self):
"""Finish up the context."""
TftpContext.end(self) # <--
self.metrics.end_time = time.time()
log.debug("Set metrics.end_time to %s", self.metrics.end_time)
self.metrics.compute()
TftpContextClientDownload.end
звонки TftpContext.end
:
class TftpContext(object):
...
def end(self):
"""Perform session cleanup, since the end method should always be
called explicitely by the calling code, this works better than the
destructor."""
log.debug("in TftpContext.end")
self.sock.close()
if self.fileobj is not None and not self.fileobj.closed:
log.debug("self.fileobj is open - closing")
self.fileobj.close() # <--
а также TftpContext.end
закрывает файл