python3 -- subprocess,excel读写库实践整理

实践项目:统计VS编译环境下程序的全局变量大小

1. 项目需求

统计当前在PC上运行的程序的全局变量大小,并以Excel表格形式展现

2. 需求分解

该需求可分解为以下几个步骤,也即需要python介入的几个点:
2.1 寻找需要进行全局变量统计的以.obj为尾缀的文件
2.2 对找到的文件,利用VS工具dumpbin.exe进行obj文件解析
2.3 通过对obj文件的解析输出,检索需要的BSS段及DATA段大小信息
2.4 将检索出的信息,写入到excel表格中

3. 各需求点涉及到的python知识

3.1 寻找特定尾缀的文件

python对文件及目录的操作提供的包主要为os.path包,通过使用os.path.splitext(文件名)即可获取一个元祖(文件前缀文件后缀

>>>import os
>>>os.path.splitext("filename.obj")
('filename', '.obj')

实例代码:搜寻入参(目录)下所有以.obj为尾缀的文件名

if len(sys.argv) != 2:
    print("Param number is invalid! Please input 1 param(dir to search)")
    sys.exit()

if not os.path.exists(sys.argv[1]):
    print("path(%s) is not exist!" % sys.argv[1])
    sys.exit()

root, dirs, files = genRDF.send(None)
for file in files:
    if os.path.splitext(file)[1] == ".obj":
        #以下为对检索出的以.obj为尾缀的文件file做操作

扩展:拆分路径及完整文件名: os.path.split(“包含文件名的路径”)

>>>import os
>>> os.path.split("d:/software/filename.txt")
('d:/software', 'filename.txt')

3.2 利用VS工具dumpbin.exe对文件做解析

在cmd环境下,利用VS提供的目标文件解析工具dumpbin,可以实现解析目标文件中各段大小

D:\vsPrj\dump\dump\dump\Debug>dumpbin /summary dump.obj
Microsoft (R) COFF/PE Dumper Version 14.00.23026.0
Copyright (C) Microsoft Corporation.  All rights reserved.

Dump of file dump.obj

File Type: COFF OBJECT

  Summary

           8 .data
         BA8 .debug$S
          44 .debug$T
          74 .drectve
           4 .rtc$IMZ
           4 .rtc$TMZ
          27 .text$mn

通过在cmd中的输出,可以看到 .data段的大小为8byte,(该文件为测试用,只初始化了两个int类型的非0变量,故.data段为8byte)。
利用python的subprocess包,可以实现shell的命令执行及返回结果的获取,以便后续继续对获取的结果进行处理
实例代码:利用subprocess包进行cmd下的命令执行

import subprocess
proc = subprocess.Popen(args = ['dumpbin', '/summary', file], stdout=subprocess.PIPE, shell=True, encoding='gbk')
filelines = proc.stdout.readlines()
#filelines 是以行为元素的列表
#encoding 需要以gbk编码解码才可以正确显示

3.3 获取BSS段及DATA段大小

从3.2中在cmd下执行dumpbin指令输出中可以看出,字段及其大小是分别在单独一行显示的,故可以简单地通过关键字“.data”及”.bss”搜索得知是否是需要进行处理的行,进而进行大小的获取
实例代码:通过关键字进行段大小的获取

BSS_SEGMENT = '.bss'
DATA_SEGMENT = '.data'

for line in filelines:
    if line.find(DATA_SEGMENT) != -1:                     #'.data'关键字在该行
        sizeDATA = int(line[0:line.find(DATA_SEGMENT)])   #获取DATA段大小
    if line.find(BSS_SEGMENT) != -1:                      #'.bss'关键字在该行
        sizeBSS = int(line[0:line.find(BSS_SEGMENT)])     #获取BSS段大小

3.4 将段大小数据写入excel中

excel的读写涉及到3个包:
xlrd – 用于对Excel进行只读操作
xlwt – 用于对Excel进行只写(新建写)操作
xlutils.copy – 用于将Excel从读模式转换为写模式(Copy an :class:xlrd.Bookinto an :class:xlwt.Workbook`)

对于该实例,需要对Excel进行追加写,故需用xlrd及xlutils.copy将Excel转换为xlwt.Workbook类
实例代码:将结果追加写入已存在的Excel文件x1.xls中

#读文件函数定义
def open_excl_read(file = 'file.xls'):
    try:
        data = xlrd.open_workbook(file)
        return data
    except Exception as e:
        print(str(e))
        return None

#excel读取
excel2read = open_excl_read("./x1.xls")
if excel2read == None:
    print("Excel file not exist")
    sys.exit()

#excel转换
excel2write = copy(excel2read)        
wtTable = excel2write.get_sheet(0)            #获取Excel的第一个Sheet(编号为0)
wtTable.write(Row1, Column1, sizeBSS)         #将sizeBSS写入对应行列格中(行列从0开始算起)
wtTable.write(Row2, Column2, sizeDATA)        #将sizeDATA写入对应行列格中(行列从0开始算起)
excel2write.save('./x1.xls')                  #写入后,进行存储

4. 完整代码

#-*- coding: utf-8 -*-
import sys
import os
import xlrd
import xlwt
from xlutils.copy import copy
import subprocess

FILE_NAME_COL = 2
BSS_COL = 3
DATA_COL = 4
START_ROW = 4
BSS_SEGMENT = '.bss'
DATA_SEGMENT = '.data'

def open_excl_read(file = 'file.xls'):
    try:
        data = xlrd.open_workbook(file)
        return data
    except Exception as e:
        print(str(e))
        return None
def open_excl_write(file = 'file.xls'):
    try:
        data = xlwt.Workbook(encoding='utf-8', style_compression=0)
        return data
    except Exception as e:
        print(str(e))
        return None

if __name__ == '__main__':
    if len(sys.argv) != 2:
        print("Param number is invalid! Please input 1 param(dir to search)")
        sys.exit()

    if not os.path.exists(sys.argv[1]):
        print("path(%s) is not exist!" % sys.argv[1])
        sys.exit()

    #root,dirs,files = os.walk(sys.argv[1])
    curRow = START_ROW

    excel2read = open_excl_read("./x1.xls")
    if excel2read == None:
        print("Excel file not exist")
        sys.exit()

    excel2write = copy(excel2read)        
    wtTable = excel2write.get_sheet(0)

    genRDF = os.walk(sys.argv[1])
    root, dirs, files = genRDF.send(None)
    for file in files:
        if os.path.splitext(file)[1] == ".obj":
            sizeBSS = 0
            sizeDATA = 0
            #print(file)
            #open excel

            #get the size of data and bss field
            filename = os.path.splitext(file)[0] + '.c'

            proc = subprocess.Popen(args = ['dumpbin', '/summary', file], stdout=subprocess.PIPE, shell=True, encoding='gbk')

            filelines = proc.stdout.readlines()
            for line in filelines:
                if line.find(DATA_SEGMENT) != -1:
                    sizeDATA = int(line[0:line.find(DATA_SEGMENT)])
                if line.find(BSS_SEGMENT) != -1:
                    sizeBSS = int(line[0:line.find(BSS_SEGMENT)])

            wtTable.write(curRow, FILE_NAME_COL, filename)
            wtTable.write(curRow, BSS_COL, sizeBSS)
            wtTable.write(curRow, DATA_COL, sizeDATA)

            curRow += 1

    excel2write.save('./x1.xls')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值