解決華為舊備份數(shù)據(jù)導(dǎo)出問題
使用低版本華為備份軟件得到的微信備份文件為一個(gè)com.tencent.mm.apk文件和一個(gè)com.tencent.mm.db文件。
用sqlite數(shù)據(jù)庫管理工具打開com.tencent.mm.db,發(fā)現(xiàn)只有三個(gè)表,其中apk_file_info表中儲(chǔ)存了所有文件名和索引號(hào),apk_file_data中則存儲(chǔ)了文件數(shù)據(jù)。索引號(hào)為-1的是目錄,索引號(hào)大于0的是有用的文件。

在apk_file_data中索引號(hào)相同的是同一個(gè)文件,每個(gè)文件被切成若干個(gè)8K以內(nèi)的碎片進(jìn)行存儲(chǔ),導(dǎo)出時(shí)需要拼接起來再導(dǎo)出。

導(dǎo)出文件數(shù)據(jù)的python代碼如下:
import
?sqlite3
import
?os
conn?
=
?sqlite3.connect(
'com.tencent.mm.db'
)
cursor?
=
?conn.cursor()
cursor.execute(
"SELECT?count(*)?FROM?apk_file_info"
)
all
?=
?cursor.fetchone()[
0
]
cursor.execute(
"SELECT?file_path,file_index?FROM?apk_file_info"
)
result?
=
?cursor.fetchall()
count?
=
?0
while
?(count?<?
all
):
??
if
?(result[count][
1
]?>?
0
):
??????
fullname?
=
?result[count][
0
]
??????
findex?
=
?result[count][
1
]
??????
dirname,filename?
=
?os.path.split(fullname)
??????
fpath
=
"."
?+
?dirname
??????
fname
=
"."
?+
?fullname
??????
isExists
=
os.path.exists(fpath)
??????
if
?not
?isExists:
??????????
os.makedirs(fpath)
??????
with?
open
(fname,?
"wb"
)?as?output_file:
????????
cursor.execute(
"SELECT?count(*)?FROM?apk_file_data?WHERE?file_index?=?"
?+
?str
(findex))
????????
total?
=
?cursor.fetchone()[
0
]
????????
cursor.execute(
"SELECT?file_data?FROM?apk_file_data?WHERE?file_index?=?"
?+
?str
(findex))
????????
acount
=
0
????????
while
?(acount?<?total):
??????????
ablob?
=
?cursor.fetchone()
??????????
output_file.write(ablob[
0
])
??????????
acount?
=
?acount
+
1
??
count?
=
?count?
+
?1
cursor.close()
conn.close()
將代碼保存為out.py后與com.tencent.mm.db文件放在同一目錄下,python out.py運(yùn)行即可在當(dāng)前目錄下導(dǎo)出所有文件。生成目錄為data/data/com.tencent.mm。

比較懶,沒有加注釋和提示信息。實(shí)際使用時(shí)請(qǐng)自行添加提示信息和異常處理代碼。如果導(dǎo)出文件數(shù)據(jù)較多程序效率比較低,可自行優(yōu)化,代碼僅供參考。
標(biāo)簽: