Как подать файл на вход

Рейтинг: 0Ответов: 1Опубликовано: 01.07.2023

Извините за глупый вопрос, но как подать файл на вход программы? Попробовал разные способы, но все равно не видит файл.

import array
import sys
import struct
import os

SECTOR_SIZE = 512


def sizemb(num, suffix='B'):
    for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']:
        if abs(num) < 1024.0:
            return "%3.1f%s%s" % (num, unit, suffix)
        num /= 1024.0
    return "%.1f%s%s" % (num, 'Yi', suffix)


class VmdkParser:
    def __init__(self, i, filesize):
        self.i = i
        self.errors = []
        self.filesize = filesize
        self.blocks = [None] * int(filesize / SECTOR_SIZE)

    def d(self, msg, offset=-1):
        if offset == -1:
            offset = self.i.tell()
        print("[%12d] %s" % (offset, msg))

    def e(self, msg, offset=-1):
        if offset == -1:
            offset = self.i.tell()
        msg = "[%12d] ERROR %s" % (offset, msg)
        self.errors.append(msg)
        print(msg)

    def parse_magic(self):
        self.magic = self.i.read(4)
        if self.magic == b"COWD":
            self.d("Version 3 header found")
            self.version = 3
        elif self.magic == b"KDMV":
            self.d("Version 4 header found")
            self.version = 4
        else:
            self.d("Invalid magic string %s" % self.magic)
            raise Exception("Could not determine file type")

    def parse_v3_header(self):
        hdr = struct.unpack("<10I", self.i.read(40))  # read 10 32bit unsigned LE ints
        self.subversion = hdr[0]
        self.flags = hdr[1]
        self.capacity = hdr[2]
        self.granularity = hdr[3]
        self.gd_offset = hdr[4]
        self.gd_size = hdr[5]
        self.used_sectors = hdr[6]
        self.gt_size = 4096

    def parse_v4_header(self):
        hdr = struct.unpack("<II4QI3Q5cH", self.i.read(75))  # read v4 header structure
        self.subversion = hdr[0]
        self.flags = hdr[1]
        self.capacity = hdr[2]
        self.granularity = hdr[3]
        self.gd_offset = hdr[7]
        self.gt_size = hdr[6]
        # calculation from https://github.com/qemu/qemu/blob/master/block/vmdk.c:688
        l1_sectors = self.gt_size * self.granularity
        self.gd_size = int((self.capacity + l1_sectors - 1) / l1_sectors)

    def print_header(self):
        self.d("-- Header info --")
        self.d(
            "Capacity %d blocks (%.2f gb)" % (self.capacity, float(self.capacity) * SECTOR_SIZE / (1024 * 1024 * 1024)))
        self.d("Grain size %d" % self.granularity)
        self.d("GD Offset %d" % self.gd_offset)
        self.d("GD Size %d" % self.gd_size)
        self.d("GT Size %d" % self.gt_size)
        self.d("Filesize %d" % self.filesize)
        self.d("----")

    def parse_gd(self):
        self.reserve_block(0, 0, 0)
        self.reserve_block(1, 0, 0)
        self.gtes = 0
        self.gts = 0
        o = self.gd_offset * SECTOR_SIZE
        self.i.seek(o)
        self.gd = struct.unpack("<%dI" % self.gd_size, self.i.read(self.gd_size * 4))
        ctr = 0
        for gde in self.gd:
            if gde == 0:
                ctr += 1
                continue
            self.d("GDE %d:%d" % (ctr, gde), o + ctr * 4)
            for i in range(0, 4):
                self.reserve_block(gde + i, ctr, 0)
            self.parse_gt(ctr, gde)
            ctr += 1

    def parse_gt(self, gd, gde):
        o = gde * SECTOR_SIZE
        self.i.seek(o)
        gt = struct.unpack("<%dI" % self.gt_size, self.i.read(self.gt_size * 4))
        ctr = 0
        self.gts += 1
        for gte in gt:
            gteo = o + ctr * 4
            if gte == 0:
                ctr += 1
                continue
            self.gtes += 1
            self.d(" GTE %d,%d:%d" % (gd, ctr, gte), gteo)
            if gte > self.capacity:
                self.e("gte %d out of bounds" % gte, gteo)
            for i in range(0, self.granularity):
                self.reserve_block(gte + i, gd, ctr)
            ctr += 1

    def reserve_block(self, idx, gd, gt):
        # print("Reserving %d for %d,%d" %(idx, gd,gt))
        if self.blocks[idx] != None:
            self.e("Block %d already reserved by %d,%d" % (idx, self.blocks[idx][0], self.blocks[idx][1]))
        else:
            self.blocks[idx] = [gd, gt]

    def check_blocks(self):
        self.used_blocks = 0
        for idx, b in enumerate(self.blocks):
            if b == None:
                # self.d("Free block %d" % idx, idx * SECTOR_SIZE)
                pass
            else:
                self.used_blocks += 1
        expect_used = self.gtes + self.gts * 4 + 2
        if self.used_blocks != expect_used:
            self.e("Expected %d blocks used, found %d" % (expect_used, self.used_blocks))

        if self.used_sectors != None and self.used_sectors != expect_used:
            self.e("Expected %d blocks used, found %d in v3 header" % (expect_used, self.used_sectors))

    def parse_header(self):
        if self.version == 4:
            self.parse_v4_header()
        elif self.version == 3:
            self.parse_v3_header()
        else:
            raise Exception("No header found")

    def parse(self):
        self.parse_magic()
        self.parse_header()
        self.print_header()
        self.parse_gd()
        self.check_blocks()
        filesize_estimation = self.gtes * SECTOR_SIZE * self.granularity
        self.d("Parsing complete: %d grains (%s), %d gts, filesize %s, %d used_blocks, %d errors" % (
        self.gtes, sizemb(filesize_estimation), self.gts, sizemb(self.filesize), self.used_blocks, len(self.errors)))


def main(filename):
    inputfile = None
    try:
        fsize = os.stat(filename).st_size
        inputfile = open(filename, 'rb')

    except:
        print("Can't open file")
        sys.exit(1)
    p = VmdkParser(inputfile, fsize)
    try:
        p.parse()
    except Exception as e:
        print(e.message)


if (len(sys.argv) < 2):
    print("Please give me a nice vmdk file!")
    sys.exit(1)
main(sys.argv[1])

Ответы

▲ 0

Как вы запускаете эту программу?

Надо из терминала (cmd в windows) ввести комманду:

python <ИМЯ ФАЙЛА ПРОГРАММЫ> <ИМЯ ФАЙЛА VDMK>.vdmk

Всё должно заработать (если конечно код написан правильно 😄).