I know this is a repeat but I've looked through the answers and none of them make sense to why I'm getting ValueError: I/O operation on closed file in this specific python 2.7 function written here.
No error when separating this out to a stand alone sciptlet of:
import hashlib
import sys
sha256_hash = hashlib.sha256()
filename = 'result.txt'
with open(filename,"rb") as f:
# Read and update hash string value in blocks of 4K
for byte_block in iter(lambda: f.read(4096),b""):
sha256_hash.update(byte_block)
print(sha256_hash.hexdigest())
f.close()
But when I put this into a defined function I get a ValueError on the print function.
def sha256hashcheck():
with open( 'goldresult.txt' ,"rb") as f:
# Read and update hash string value in blocks of 4K
for byte_block in iter(lambda: f.read(4096),b""):
sha256_hash.update(byte_block)
print(sha256_hash.hexdigest())
f.close()
sha256hashcheck()
All the other defined functions run the close() method before exiting the function, plus I make a test file on the side that no function calls and use that as the open in the def and I still get the ValueError exception
File "parse-o365-ip-addrs.py", line 61, in sha256hashcheck
print(sha256_hash.hexdigest())
ValueError: I/O operation on closed file
Any pointers or suggestions?
TY
Here is my entire script .. yes I'm new to python .. :)
# Initial code - https://gist.github.com/cdodd/7679fb9c5f2a2e4700c7a9c7a53e2a19 (cdodd)
import xmltodict
from socket import inet_ntoa
from struct import pack
import sys
import urllib
import hashlib
# Read from URL
data = urllib.urlopen('https://support.content.office.net/en-us/static/O365IPAddresses.xml').read()
doc = xmltodict.parse(data)
# Read from local file
# doc = xmltodict.parse(open('/path/to/file.xml').read())
# set your variables
subnettestVar = 'test.txt'
subnetresultVar = 'result.txt'
subnetgoldVar = 'goldresult.txt'
sha256_hash = hashlib.sha256()
#define your functions or classes
def calcDottedNetmask(mask):
bits = 0xffffffff ^ (1 << 32 - mask) - 1
return inet_ntoa(pack('>I', bits))
# Work to be done, if x['@name'] still shells exception (KeyError) on 'OneNote' because OneNote has no IPv4 address
# Still need to work out either .get (dict) or try - exception errorhandling for that issue
def getsubnets():
sys.stdout = open( subnettestVar , 'w')
for x in doc['products']['product']:
if x['@name'] in ['o365', 'Identity', 'Planner', 'ProPlus', 'Yammer', 'Teams', 'SPO', 'LYO', 'WAC']:
for y in x['addresslist']:
if y['@type'] == 'IPv4':
for ip in y['address']:
if '/' not in ip:
ip, dot_mask = (ip, '255.255.255.255')
else:
ip, cidr_mask = ip.split('/')
dot_mask = calcDottedNetmask(int(cidr_mask))
print 'network-object ' + ip + ' ' + dot_mask
print
sys.stdout.close()
def removeblanklines():
with open( subnettestVar ,'r+') as file, open( subnetresultVar ,"w") as outfile:
for i in file.readlines():
if not i.strip():
continue
if i:
outfile.write(i)
file.close()
outfile.close()
def sha256hashcheck():
with open( 'goldresult.txt' ,"rb") as f:
# Read and update hash string value in blocks of 4K
for byte_block in iter(lambda: f.read(4096),b""):
sha256_hash.update(byte_block)
print(sha256_hash.hexdigest())
f.close()
#Run your full program with all functions, classes and variables
getsubnets()
removeblanklines()
sha256hashcheck()
All, thanks for the pointers, ShadowRanger hit the nail on the head - me being stupid and calling sys.stdout.close() .
Created a proper "with" "as" to open the file and properly call file open, just had to fuss with the print lines and call filename.write instead of relying on print statements which are console instead of file specific.
Please feel free to claim an Answer if you want ...
TY
Making an answer from my comment:
The error you're getting is for the print
(hexdigest
doesn't use a file at all), which indicates you've closed sys.stdout
somehow. As you stated, your real code included sys.stdout.close()
, which would make all default print
calls fail with this error. Don't close sys.stdout
and/or pass file=somefileobj
as a keyword argument to print
so it doesn't use sys.stdout
.
User contributions licensed under CC BY-SA 3.0