Образ диска Python

Пытаюсь сделать скрипт для создания образа инфы (типа формата .dd) на питоне. Первоначально начинался как проект по созданию еще одного шестнадцатеричного отладчика, и его больше заинтересовала попытка получить необработанные данные с диска. что превратилось в желание сначала создать образ диска. В любом случае, я искал около недели или около того и обнаружил, что лучший способ получить информацию с диска на меньших дисках выглядит примерно так:

with file("/dev/sda") as f:
 i=file("~/imagingtest.dd", "wb")
 i.write(f.read(SIZE))

где размер - это размер диска. Проблема в том, что это, кажется, хорошо известная проблема, попытка использовать большие диски проявляется как (даже в моем случае общий размер 250059350016 байт):

«OverflowError: Python int слишком велик для преобразования в C long»

Есть ли более подходящий способ обойти эту проблему? Поскольку он отлично работает для небольшой флешки, но попытка создать образ диска не удалась.

Я видел упоминание о возможной итерации по размеру сектора (512) по количеству секторов (в моем случае 488397168), однако хотел бы точно проверить, как это сделать так, чтобы это было функциональным.

Заранее спасибо за любую помощь, извините за любое невежество, которое вы легко заметите.


person Ferasdour    schedule 09.06.2013    source источник
comment
Читать данные блоками? Вы действительно хотите открыть устройство в двоичном режиме, open('/dev/sda', 'rb') если вы это делаете. Когда вы дойдете до конца устройства, .read(blocksize) вернет пустую строку.   -  person Martijn Pieters    schedule 09.06.2013
comment
Копирует ли это решение все, включая метаданные?   -  person Daniel Siegel    schedule 05.08.2020


Ответы (2)


Да, вот как вы должны это сделать. Хотя вы можете увеличить размер сектора, если хотите.

with open("/dev/sda",'rb') as f:
    with open("~/imagingtest.dd", "wb") as i:
        while True:
            if i.write(f.read(512)) == 0:
                break
person korylprince    schedule 09.06.2013
comment
Это тоже выглядит хорошо. Понятия не имею, как я об этом не подумал. :( Если есть что-то хорошее на этом сайте, это заставляет меня осознать свою глупость. хахаха. Хотя мне нравится способ, которым Мартейн получил свой ответ. Судя по всему, он делает то же самое. Спасибо за помощь! - person Ferasdour; 09.06.2013
comment
Хорошо, способ украсть прожектор! ржунимагу. Пробовал их обоих, этот, кажется, лучше соответствует моим конкретным потребностям, когда я их запускал. :) - person Ferasdour; 09.06.2013
comment
@Ferasdour: по сути, они делают одно и то же. i.write() возвращает количество записанных байтов, запись пустой строки возвращает 0. - person Martijn Pieters; 09.06.2013
comment
Есть идеи, возможно ли что-то подобное в Windows? - person NoBugs; 17.04.2017

Прочитайте данные в блоках. Когда вы дойдете до конца устройства, .read(blocksize) вернет пустую строку.

Вы можете использовать iter() с часовым, чтобы легко сделать это в цикле:

from functools import partial

blocksize = 12345

with open("/dev/sda", 'rb') as f:
    for block in iter(partial(f.read, blocksize), ''):
        # do something with the data block

Вы действительно хотите открыть устройство в двоичном режиме, 'rb' если хотите убедиться, что не происходит перевода строк.

Однако, если вы пытаетесь создать копию в другой файл, вам нужно посмотреть shutil.copyfile():

import shutil

shutil.copyfile('/dev/sda', 'destinationfile')

и он позаботится об открытии, чтении и написании за вас. Если вы хотите иметь больший контроль над размером блока, используемого для этого, используйте shutil.copyfileobj()< /a>, откройте сами файловые объекты и укажите размер блока:

import shutil

blocksize = 12345

with open("/dev/sda", 'rb') as f, open('destinationfile', 'wb') as dest:
    shutil.copyfileobj(f, dest, blocksize)
person Martijn Pieters    schedule 09.06.2013
comment
кажется довольно законным прямо здесь. :) И да, я понимаю о двоичной части, забыл добавить ее туда, когда набирал вопрос. :/ Прости за это. Я попробую и посмотрю, что я могу сделать. - person Ferasdour; 09.06.2013