2014-09-22 11 views
7

jestem generowania liczbę plików csv dynamicznie, przy użyciu następującego kodu:Jak skompresować plik CSV bezpośrednio do archiwum zip?

import csv 
fieldnames = ['foo1', 'foo2', 'foo3', 'foo4'] 
with open(csvfilepath, 'wb') as csvfile: 
    csvwrite = csv.DictWriter(csvfile, delimiter=',', fieldnames=fieldnames) 
    csvwrite.writeheader() 
    for row in data: 
     csvwrite.writerow(row) 

Aby zaoszczędzić miejsce, chcę je skompresować.
Korzystanie z modułu gzip jest dość proste:

with gzip.open("foo.gz", "w") as csvfile : 
    csvwrite = csv.DictWriter(csvfile, delimiter=',', fieldnames=fieldnames) 
    csvwrite.writeheader() 
    for row in data: 
     csvwrite.writerow(row) 

Ale chcę plik w formacie „zip”.

Próbowałem modułu zipfile, ale nie jestem w stanie bezpośrednio zapisywać plików w archiwum zip.

Zamiast tego, muszę napisać plik csv na dysk, skompresować go w pliku zip za pomocą następującego kodu, a następnie usunąć plik csv.

with ZipFile(zipfilepath, 'w') as zipfile: 
    zipfile.write(csvfilepath, csvfilename, ZIP_DEFLATED) 

Jak mogę napisać plik csv bezpośrednio na skompresowanym pliku ZIP podobnym do gzip?

+0

@ J.F.Sebastian dzięki za komentarz. zaktualizowane –

Odpowiedz

7

Użyj obiektu cStringIO.StringIO naśladować plik:

with ZipFile(your_zip_file, 'w', ZIP_DEFLATED) as zip_file: 
    string_buffer = StringIO() 
    writer = csv.writer(string_buffer) 

    # Write data using the writer object. 

    zip_file.writestr(filename + '.csv', string_buffer.getvalue()) 
+0

fajne. dzięki za szybką odpowiedź. robi się to z niewielką modyfikacją. Sprawdź moją odpowiedź. –

+1

W Pythonie 3 przeniesiono to do [io.StringIO] (https://docs.python.org/3.6/library/io.html#io.StringIO). – Teepeemm

1

Dzięki kroolik Zrobione z niewielkimi modyfikacjami.

with ZipFile(your_zip_file, 'w', ZIP_DEFLATED) as zip_file: 
    string_buffer = StringIO() 
    csvwriter = csv.DictWriter(string_buffer, delimiter=',', fieldnames=fieldnames) 
    csvwrite.writeheader() 
    for row in cdrdata: 
     csvwrite.writerow(row) 
    zip_file.writestr(filename + '.csv', string_buffer.getvalue()) 
+2

uwaga: 'StringIO()' gromadzi dane w pamięci. Nie nadaje się, jeśli nieskompresowane dane nie mieszczą się w pamięci. – jfs

+0

@ J.F.Sebastian thnks za komentarz. Czy możesz zaproponować lepszą alternatywę? –

+2

użyj dowolnego formatu kompresji obsługującego przesyłanie strumieniowe – jfs

Powiązane problemy