質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Q&A

解決済

1回答

2592閲覧

Python2.7におけるzipファイルの解凍方法について/ImageJ/Jython

Savanof

総合スコア33

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

0グッド

0クリップ

投稿2020/12/16 12:38

編集2020/12/17 06:59

前提・実現したいこと

ImageJという画像解析ソフトを使っている関係で、やむを得ずPython2.7でコードを書いています。

Python2.7でzipファイルを解凍したいのですが、する事ができません。

OutletHDDというフォルダーにRoiSet.zipというzipファイルがあり、それをhogeというフォルダーに解凍したいです。

発生している問題・エラーメッセージ

TypeError: character mapping must return integer, None or unicode

該当のソースコード

Python2

1import zipfile 2from ij.plugin.frame import RoiManager 3from ij.process import ImageProcessor 4zippath = "C:\Users\For Programming\Documents\Python Scripts\OutletHDD\RoiSet.zip" 5 6 7ZipObj = zipfile.ZipFile(zippath) 8ZipObj.extractall("C:\Users\For Programming\Documents\Python Scripts\OutletHDD\hoge") #Zipファイルを解凍して移動 9ZipObj.close()

試したこと

unicode型,str型のバグかと思い、str(),unicode()等を行ってみたいのですが、上手く動きませんでした。

補足情報(FW/ツールのバージョンなど)

windows10 64bit

2.7.2 (v2.7.2:925a3cc3b49d, Mar 21 2020, 10:12:24)
[Java HotSpot(TM) 64-Bit Server VM (Oracle Corporation)]

追記

path周りの環境が完全にぶっ壊れてる事を疑って、shuntil系のcopyやmoveを試してみたのですが問題無く動きました。

今回、解凍しようとしていたzipファイルの中身はroiファイル(.roi)という特殊なファイル形式なのですが、他のファイル形式(例えばtxt)では問題無く解凍する事ができました。

恐らくPythonの問題ではなく、ImageJ側の問題の方が強いです。

追記2

この様なコードでzipフォルダーの中のファイルパスをの文字コードを確かめてみたのですが、全てunicode型でした。

import zipfile with zipfile.ZipFile("C://Users//For Programming//Documents//Python Scripts\OutletHDD//RoiSet.zip") as existing_zip: lis = existing_zip.namelist() print(lis) for i in lis: print(isinstance(i,unicode))

Daregadaさんから教えて貰った下記のリンクを見てみると、恐らく解凍できないのはzipフォルダーの中に入っているファイルが全てunicode型である事が原因だと思います。
「Python 2.7.4 fails while extracting zip files when 'member' is a unicode path.」
https://bugs.python.org/msg186264

そこでZipフォルダーの中に入っているファイルパスを全て"utf-8"型に変更しようと思ったのですが、zipフォルダーを解凍しないという条件下でどの様に変更すればいいか分かりません。

Python2

1import zipfile 2import os 3import codecs 4 5with zipfile.ZipFile(r"C:\Users//For Programming//Documents//Python Scripts//OutletHDD//RoiSet.zip") as existing_zip: 6 lis = existing_zip.namelist() 7 8for i in lis: 9 fullpath = r"C://Users//For Programming//Documents//Python Scripts//OutletHDD//RoiSet.zip" + "//" + i 10 fullpath_utf8 = fullpath.decode("utf-8") 11 os.rename(fullpath, fullpath_utf8) 12

このコードではこの様なエラーコードが出てしまいました。zipファイルの中を普通のtextファイルに変えた場合も、同様のエラーが出たので、深く調べきれていませんが、恐らくzipファイル内のファイルをrenameした時のエラーだと思います。

OSError: (0, "Couldn't rename file")

zipフォルダ内のファイルの文字コード/パスの変更はどの様に変更すればいいでしょうか?

参考にしたサイト
https://qiita.com/HidKamiya/items/c164a6ce07820f65c501

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

通常の文字列に\を使うとエスケープとして処理されるので、\と書いてください。

Diff

1-zippath = "C:\Users\For Programming\Documents\Python Scripts\OutletHDD\RoiSet.zip" 2+zippath = "C:\Users\For Programming\Documents\Python Scripts\OutletHDD\RoiSet.zip"

Diff

1-ZipObj.extractall("C:\Users\For Programming\Documents\Python Scripts\OutletHDD\hoge") 2+ZipObj.extractall("C:\Users\For Programming\Documents\Python Scripts\OutletHDD\hoge")

投稿2020/12/16 14:19

Daregada

総合スコア11990

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Savanof

2020/12/17 02:14

"\"という様にパスを書き換えてみたのですが、エラーコードは変わらず同じでした。 環境欄に追加し忘れていたのですが、使っているOSはwindows10です。 現在、ImageJ内のエディターから.pyファイルを実行しているのですが、もしかしたら自分の環境特有の問題かもしれないです。 回答ありがとうございました
Savanof

2020/12/17 03:28

いくつか質問背景を追記しました。 恐らく、Pythonの問題ではなく、ImageJ側の問題な気がします。 回答ありがとうございました。
Daregada

2020/12/17 03:34

zip内のファイル名(パス)がUnicodeで保存されているということはないですか? 「Python 2.7.4 fails while extracting zip files when 'member' is a unicode path.」 https://bugs.python.org/msg186264
Savanof

2020/12/17 04:06

下のスクリプトで判定してみたらUnicode型でした! どうやら仕様でできない様なので、ascii stringsに変換をかけて実装する方針ですかね? ``` import zipfile with zipfile.ZipFile("C://Users//For Programming//Documents//Python Scripts\OutletHDD//RoiSet.zip") as existing_zip: lis = existing_zip.namelist() print(lis) for i in lis: print(isinstance(i,unicode)) ```
Savanof

2020/12/17 07:16

zipフォルダー内のunicode型のパスをutf-8に変更する検討が自分ではつかないのですが、decode型のパスをutf-8に変更する検討が自分ではつかないのですが、何かアイデアがあったらご教授して欲しいです。
Daregada

2020/12/17 07:56

コマンドラインで動作するZIP展開ツールをPythonから実行してはどうでしょうか。 例えば、7-zipから単独で動作する7za.exeが公開されています。 https://sevenzip.osdn.jp/download.html の「7-Zip Extra」に含まれます。
Savanof

2020/12/17 08:14

シェルスクリプト?を介して実行する形ですかね? ありがとうございます。やってみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問