PythonIsBae
PythonIsBae

Reputation: 358

ValueError: I/O operation on closed file after opening file

I have this code:

import os

csv_out = 'femaleconsolidated.csv'

csv_list = [r'C:\Users\PycharmProjects\filemerger\Female\outputA.csv',
            r'C:\Users\PycharmProjects\filemerger\Female\outputB.csv',
            r'C:\Users\PycharmProjects\filemerger\Female\outputC.csv',
            r'C:\Users\PycharmProjects\filemerger\Female\outputD.csv',
            r'C:\Users\PycharmProjects\filemerger\Female\outputE.csv',
            r'C:\Users\PycharmProjects\filemerger\Female\outputother.csv']
print(csv_list)
csv_merge = open(csv_out, 'w')
for file in csv_list:
    csv_in = open(file)
    for line in csv_in:
        csv_merge.write(line)
    csv_in.close()
    csv_merge.close()
print('Verify consolidated CSV file : ' + csv_out)

The code is to merge CSVs. Surely open(file) should open the file but I get this:

    csv_merge.write(line)
ValueError: I/O operation on closed file.

What could be causing this?

Upvotes: 1

Views: 6225

Answers (4)

Sowjanya R Bhat
Sowjanya R Bhat

Reputation: 1168

csv_merge.close() this should sit outside of the for loop - since you are still writing to csv_merge in next iteration :

for file in csv_list:
    csv_in = open(file)
    for line in csv_in:
        csv_merge.write(line)
    csv_in.close()
csv_merge.close()

Upvotes: 3

Daniela Varela
Daniela Varela

Reputation: 46

If you want to writer line by line you should try this. You dont need to worry for closing the file when using this package - csv

import csv

destination = open(csv_out , 'w')
csvwriter = csv.writer(destination)
...
for line in csv_in:
    csvwriter.writerow(line)

If you just want to merge all files in a single one, there are more efficient ways to do it, not line by line. You can check this one https://www.freecodecamp.org/news/how-to-combine-multiple-csv-files-with-8-lines-of-code-265183e0854/

Upvotes: 0

Mahsa Hassankashi
Mahsa Hassankashi

Reputation: 2137

Use pandas:

import pandas as pd
import glob

dfs = glob.glob('path/*.csv') #path to all of your csv

result = pd.concat([pd.read_csv(df) for df in dfs], ignore_index=True)

result.to_csv('path/femaleconsolidated.csv', ignore_index=True)

Upvotes: 0

Aleksey
Aleksey

Reputation: 803

Your for statement should be inside the with block:

with open(csv_out, 'w') as csv_merge:
    for file in csv_list:
        csv_in = open(file)
        for line in csv_in:
            csv_merge.write(line)
        csv_in.close()
        csv_merge.close()
    print('Verify consolidated CSV file : ' + csv_out)

Upvotes: -1

Related Questions