cp932からutf-8への文字コード変換。

世の中、まだまだ文字コードの問題はなくなりません。特に日本語をはじめとするマルチバイト文字の文化圏では……。

ご多分に漏れずうちの環境でも同様で、Windows標準のFINDは率直に言って使いづらく、最近はripgrepthe Platinum Seacherなどを使っていますが。

それはともかく、プログラムからテキストファイルをいじりたいときに、文字コードが揃っていないととにかく大変です。個人的にはPCにあるすべてのテキストファイルはUTF-8であってほしいところですが、まだまだシフトJISがはびこっています。

なのでこれを一括でUTF-8に変換するにはどうすればいいかとちょっと前に検索したところ、Pythonのcodecs.StreamRecoder()を使ってストリームを流しながらcodecを通す、という方法があったのでこれを使っていました。

ところが最近pathlibをよく使うようになり、以前にos.walk()を使って取得していたディレクトリツリーのファイルリストをpathlib.Path.glob()に書き直しているときに、pathlib.Path.read_text()というのを見つけました。

Path.read_text()は以下のように使います。
from pathlib import Path

infile = Path("abc.txt")
content = infile.read_text(encoding="cp932")

outfile = Path("xyz.txt")
outfile.write_text(content, encoding="utf-8")
大きなサイズのファイルであれば読み込みサイズを加減する必要がありますが、小さいサイズならこれで十分です。明示的にファイルをopen()する必要すらありません。
あまり大きなファイルでは試していませんが、600KBのファイルを読み込んで処理するのは問題ないようです。

上記の例ではinfileoutfileを別にしていますが、Path.read_text()Path.write_text()は自動でファイルを開き、読み込み/書き込み処理をし、すみやかにファイルを閉じる、というところまでやってくれます。with open()...を使ったコンテキスト構文すら不要です。

また、ファイルは閉じられているので「読み込んですぐに文字コードを変えて書き戻す」ということもできます。
from pathlib import Path

textfile = Path("abc.txt")
content = textfile.read_text(encoding="cp932")
textfile.write_text(content, encoding="utf-8")
3行で文字コード変換できてしまいます。

おかげでコードがけっこう短くなりました。

0 件のコメント:

コメントを投稿

AstroNvimでtelescope.nvimがエラーを吐いたとき。

Windowsの環境でAstroNvimをインストールして、Find Fileしたらtelescopeがエラーを吐いてきました。 メッセージは、 Failed to run `config` for telescope.nvim ...a/lazy/telescope.nvim/...