【経緯】
意外にファイルのバイナリ書き換えとリネームにてこずったので、メモがてら。
特に「ファイルの先頭に追記」にてこずりました。。。
【要件 ※元ファイルがZipファイル想定】
- ファイルの先頭16バイトを8ずつ入れ替えする
- ファイルの先頭にバイナリで「07」を追記する
- ファイルのリネームを行う
【コード】
import os
import shutil
# デスクトップのパスを取得
def getDesktopPath():
return os.getenv("HOMEDRIVE") + os.getenv("HOMEPATH") + "\\Desktop" + "\\"
# バイナリの書き換え
def writeBinary(path):
zip = open(path, 'r+b')
# 先頭16バイトの先頭8バイトを取得
first = zip.read(8)
# 先頭16バイトの残りを取得
zip.seek(8)
second = zip.read(8)
# 先頭16バイトを8バイトずつ入れ替える
zip.seek(0)
zip.write(second)
zip.seek(8)
zip.write(first)
# 先頭1バイトに01を追加
zip.seek(0)
row = zip.readlines()
row.insert(0, chr(7))
zip.close()
add = open(path, 'w+b')
add.writelines(row)
add.close
# 指定ファイルのパス(Zipファイル想定)
targetPath = 'targetPath'
writeBinary(targetPath)
# ファイルのリネーム
# os.renameを使用してリネームした場合、リネーム後のファイルが既に存在していた場合はOSによって動作を変える
# WindowsはWindowsFileErrorが発生。Linux/Unixは上書き?
# os.rename(targetPath, os.path.abspath(getDesktopPath() + '%s.zip' % 'rename'))
# shutil.moveはmvコマンドと同じ扱いなので、ファイル上書きになる
shutil.move(targetPath, os.path.abspath(getDesktopPath() + '%s.zip' % 'rename'))
【所感】
ファイルの先頭から追記がどうしても出来なくてこんな感じになりました。
r+bでファイルを開くと末尾に追加になってしまうので、r+bで開いた状態でファイルのバイナリを全部取得→バイナリ操作→一旦開きなおして記載、みたいな感じになりました。きっともっと良い方法がある気がする。。。
ファイルのリネームはshutil.moveを使用していますが、既に同じ名前のファイルが存在している場合にも無視して上書きする動作になっているので、嫌な場合はos.renameを使用する。