大きなカンマ区切りの値(CSV)やタブ区切りの値(TSV)といった テキストデータをzipで圧縮するとだいぶ小さくなるので、 そのようにして保存しておくことも多い。 そのようなテキストファイルを読み込みたいときに、 zipファイルを扱うモジュールが利用できると便利である。
そこで、datafile.txtというテキストファイルをzip圧縮した、 datafile.zipを読み込んで、各行をプリントするだけというスクリプトを書いてみた。
Python(v3.83 windows 64bit)では、以下のようなスクリプトになる。
import io
import zipfile
def readzip():
filename = "datafile.zip"
try:
z = zipfile.ZipFile(filename, 'r')
except:
print("Opening zip failed")
exit(-1)
try:
for fname in z.namelist():
print(fname)
fp = io.TextIOWrapper(z.open(fname, 'r'))
line = fp.readline().strip()
while line:
print(line)
line = fp.readline().strip()
fp.close()
finally:
z.close()
if __name__ == '__main__':
readzip()
nimでは、zipパッケージにあるzipfilesモジュールを利用する。
import streams
import zip\zipfiles
proc readzip() =
var filename = "datafile.zip"
var z: ZipArchive
var line = ""
if not z.open(filename):
echo "Opening zip failed"
quit(1)
try:
for f in walkFiles(z):
echo f
var fs = z.getStream(f)
while fs.readLine(line):
echo line
fs.close()
finally:
z.close()
when isMainModule:
readzip()
コンパイルは、readzip.nimというファイルに書いたとすると、
nim c readzip.nimでできるが、その前にzipパッケージをインストールする必要がある。 Gitがインストールされていれば、
nimble install zipでインストールできる。 さらに、Windowsでコンパイルすると、gccでコンパイルされるときに エラーで止まってしまった。 こちらにあるように、修正するとコンパイルできた。
ついでなので、Julia(v1.5 windows 64-bit)でも書いてみた。 juliaでは、ZipFile.jlが利用できる。
using Pkg
Pkg.add("ZipFile")
としてインストールできた。
using ZipFile
function readzip()
filename = "datafile.zip"
local z
try
z = ZipFile.Reader(filename)
catch
println("Opening zip failed")
exit(-1)
end
try
for f in z.files
println(f.name)
while !eof(f)
line = readline(f)
println(line)
end
end
finally
close(z)
end
end
readzip()
Juliaでは、tryブロックもスコープを作るようで、tryブロック内で作った変数zを、
そのtryブロックから出た後でも利用するために、local z宣言をしている。
どれも似たような感じに書けたが、Juliaは、関数が充実しているからかシンプルに感じる。 whileのループは、eachline(f)を用いたforループで書くと、すっきりする。