Daniel
Daniel

Reputation: 23

Python - ValueError: I/O operation on closed file

I'm rather new to Python, but based on what I've gathered on the internet it appears that ValueError: I/O operation on closed file is based on not closing the write-to file properly.

I've tried repositioning the close statement to line up with each loop without any success.
I've also attempted to reposition where I originally open the files for writing without any success. I am sure there's an obvious mistake that I'm missing. Your help with identifying this mistake would be greatly appreciated.

import os       # Loop through files/folders
import xlrd     # Used to read Excel
import time     # Set sleep timers

directory = 'C:/Path/to/file/'

for subdir, dirs, files in   
os.walk(directory):                                                         
# Loop through directory
files = [file for file in files if file.endswith('.xls')]
out_14 = open(str("C:/path/to/file/14.out"), "w")
out_15 = open(str("C:/path/to/file/15.out"), "w")
for file in files:                                                                              # Loop through files in directory
    wb_path = os.path.join(subdir, file)
    wb = xlrd.open_workbook(wb_path)
    ws = wb.sheet_names()
    for worksheet in ws:                                                                        # Loop through worksheets
        sheet = wb.sheet_by_name(worksheet)
        num_rows = sheet.nrows - 1
        num_cells = sheet.ncols - 1
        curr_row = -1
        while curr_row < num_rows:                                                              # Loop through all rows
            temp_14 = []
            temp_15 = []
            curr_row += 1
            curr_cell = -1
            while curr_cell < num_cells:                                                        # Loop through all cells within current row
                curr_cell += 1
                # Cell Types: 0=Empty, 1=Text, 2=Number, 3=Date, 4=Boolean, 5=Error, 6=Blank
                cell_type = sheet.cell_type(curr_row, curr_cell)
                cell_value = sheet.cell_value(curr_row, curr_cell)
                if cell_type == 3:                                                              # Fix Dates yyyy/mm/dd
                    year, month, day, hour, minute, second = xlrd.xldate_as_tuple(cell_value, 0)
                    cell_value = (str(year) + "/" + str(month) + "/" + str(day))
                elif cell_type == 2:                                                            # Round numeric values
                    cell_value = round(cell_value, 3)
                temp_15.append(cell_value)
            out = str('~'.join('"{0}"'.format(item) for item in temp_15))                       # Tilde delimited while encapsulated with quotes
            out_15.write(out)
#                time.sleep(1.0)
    out_15.close()

Upvotes: 1

Views: 3258

Answers (1)

GCord
GCord

Reputation: 146

The error is actually raised when trying to write to the file after closing it. It is closed at the end of the first iteration of the loop. On the second iteration, you will get the error.

You're opening the out_15 file with mode 'w', hence you're going to overwrite it every time you open it. We can then assume you want to open and close it outside your loop for file in files.

Then why not use the more modern with statement, and enclose the for loop inside:

with open(str("C:/path/to/file/15.out"), "w") as out_15:
    for file in files:
        (...)

That way you don't have to bother closing the file, it will be automatic at the end of the with block. See this question: Valueerror : I/O operation on closed file

Other notes: - You're opening out_14 but you never use it and never close it. - Instead of str("C:/...") you can use r"c:......" : r"" is a "raw" string and it will not interpret the backslashes as escape characters. Actually str() isn't necessary in your case.

Upvotes: 1

Related Questions