2017-07-05 5 views
1

は、私が(のpython 2.7)を次のように新しいジップバッファにいくつかのCSVバッファを圧縮したい: のpython:ビュンCSVバッファ

files = [] 

csv_buffer = StringIO.StringIO() 
writer = csv.writer(csv_buffer) 
writer.writerow(["some", "csv", "data"]) 

csv_buffer.seek(0) 

files.append(csv_buffer) 

zipped_file = io.BytesIO() 

with zipfile.ZipFile(zipped_file, 'w') as zipper: 
    for i, csv_file in enumerate(files): 
     csv_file.seek(0) 
     zipper.writestr("{}.csv".format(i), csv_file.read()) 

zipped_file.seek(0) 

は、それから私は、ダウンロードするためのDjangoのビューを介して結果バッファを派遣します。しかし、私がジップを開くと、ファイル(0.csv)が見つかりますが、正しくエンコードされません。私はそれをUTF-8としてエンコードしたいと思います。

次のように、私も試してみました:

zipper.writestr("{}.csv".format(i), csv_file.read().encode("utf-8")) 

をそれは何の違いが行われていません。また

zipped_file = StringIO.StringIO() 

zipped_file = io.BytesIO() 

を変更することは助けにはなりませんでした。 何が間違っていたかについてのアイデアは非常に高く評価されるでしょう!

EDIT:私のソリューション

そうでない場合は便利で面白い答えにもかかわらず、私は

 zipper.writestr(zipfile.Zipinfo("foo.csv"), csv_file.read()) 

いけに

zipper.writestr("{}.csv".format(i), csv_file.read()) 

を変更することで問題を解決し以下理由を知っているが、それが作られましたそれは動作する

答えて

2

だから、CSVを正しくエンコードしていないようです。 Unicode入力をサポートしていません

csvモジュールのこのバージョンを:

csv moduleドキュメント(Pythonの2.7)にこのノートを見てみましょう。また、現在、ASCII NUL文字に関するいくつかの問題があります。したがって、安全であるためには、すべての入力がUTF-8または印刷可能なASCIIでなければなりません。セクションExamplesの例を参照してください。

writer = UnicodeWriter(csv_buffer) 

代わりに:

writer = csv.writer(csv_buffer) 
だけではなく、 csv.writerUnicodeWriter(ドロップイン交換)を使用

class UnicodeWriter: 
    """ 
    A CSV writer which will write rows to CSV file "f", 
    which is encoded in the given encoding. 
    """ 

    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): 
     # Redirect output to a queue 
     self.queue = cStringIO.StringIO() 
     self.writer = csv.writer(self.queue, dialect=dialect, **kwds) 
     self.stream = f 
     self.encoder = codecs.getincrementalencoder(encoding)() 

    def writerow(self, row): 
     self.writer.writerow([s.encode("utf-8") for s in row]) 
     # Fetch UTF-8 output from the queue ... 
     data = self.queue.getvalue() 
     data = data.decode("utf-8") 
     # ... and reencode it into the target encoding 
     data = self.encoder.encode(data) 
     # write to the target stream 
     self.stream.write(data) 
     # empty queue 
     self.queue.truncate(0) 

    def writerows(self, rows): 
     for row in rows: 
      self.writerow(row) 

この

は、それらが参照している例であります

または、ca n、Python 3よりPython 2よりもはるかに優れたUnicodeを扱えます。

+0

ありがとうございました。 UnicodeWriterではまだ成功していません。 CSVバッファは今はOKですが、まだ解凍しようとすると、何とか破損してしまいます。もし私が圧縮されていないCSVをダンプすると、00000000:0000 0000 0000 0000 0000 0000 0000 ............. – DeBaze

+0

私は同じことをしようとするが、バッファの代わりにファイルに書き込むと、 。これは回避策かもしれませんが、私はまだディスク上のファイルの代わりにバッファーを使いたいと思います。何が問題なの? – DeBaze

+0

私はちょうどあなたの 'zipped_file'をディスク上のファイル(' f.write(zipped_file.getvalue()) 'で保存しようとしました)、そのファイルは完璧に良いzipファイルです。 UTF-8でエンコードされたテキスト)。それは、あなたが質問で省略したアプリケーションのどこかに問題があることを私に伝えます.Djangoが正しくこのバッファを読み込んで提供していますか? – randomir