[英]Getting a ValueError when making a NamedTemporaryFile in python
[英]Python NamedTemporaryFile - ValueError When Reading
我在用Python寫入NamedTemporaryFile並將其讀回時遇到問題。 該函數通過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是否可能關閉文件? 我讀到NamedTemporaryFile中可能存在一個錯誤導致此問題? 為什么在with
塊定義的引用超出范圍之前關閉文件?
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
關閉文件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.