Блочное и файловое копирование решают одну и ту же бытовую задачу - перенести данные с одного носителя на другой - совершенно разными способами, и путаница между ними стоит администраторам немало нервов. Первый метод читает устройство как непрерывную ленту секторов, не вникая в смысл байтов. Второй ходит по каталогам через драйвер файловой системы и пересоздаёт каждый файл по имени. Из этого фундаментального различия вытекает всё остальное: загрузочность клона, скорость на мелких файлах, судьба ACL и жёстких ссылок, поведение на SSD и возможность ужать систему на диск меньшего объёма. Ниже разбираем оба подхода на практике Windows и Linux, без маркетинговой шелухи.

Блочное копирование как сырой поток секторов

Классический представитель блочного подхода - утилита dd и её наследники: Clonezilla, всякие sector-by-sector режимы коммерческих клонировщиков. Идея проста до примитива: источник открывается как блочное устройство (в Windows это путь вида \\.\PhysicalDrive0), читается последовательно кусками по несколько мегабайт, и каждый сектор пишется в то же смещение на целевом диске. Файловой системы для такого инструмента не существует. Есть только LBA-адреса от нуля до конца устройства.

Из этого следует главное свойство метода: копия получается побайтово идентичной оригиналу в пределах скопированного объёма. Вместе с данными пользователя переезжают таблица разделов MBR или GPT, загрузочные коды в первых секторах, резервные копии таблиц в конце диска, неразмеченные области между разделами, скрытые служебные разделы, следы удалённых файлов в свободном месте и вообще всё, что физически записано на пластинах или в ячейках NAND. Форензика любит такой режим именно за полноту: из незанятого пространства потом можно вытащить стёртые данные.

Плата за полноту - негибкость. Целевой диск должен быть не меньше исходного, иначе банально не влезут хвостовые сектора. Свободное место копируется наравне с занятым, то есть терабайтный диск с системой на сто гигабайт будет гоняться долгие часы, хотя полезных данных там всего десятая часть. Умные клонировщики частично снимают эту боль: они анализируют карту занятых кластеров (bitmap NTFS, extent-деревья ext4) и читают только используемые области, но логическая структура разделов всё равно воспроизводится один в один. Это уже гибридный режим, но по духу он остаётся блочным: смысл байтов по-прежнему никого не интересует.

Файловое копирование и путь через драйвер файловой системы

Файловый метод работает этажом выше. Инструмент - Explorer, robocopy, xcopy, cp, rsync - перечисляет каталоги, и для каждого найденного объекта проделывает полный цикл через API файловой системы. На Windows под капотом каждого маленького файла прячется удивительно много работы.

Сначала идёт поиск: путь разбирается по компонентам, каждый каталог открывается и просматривается, в NTFS имя ищется в B-дереве индекса каталога, а запись файла - в MFT, главной таблице файлов, где каждой записи отведён килобайт. Затем читаются экстенты - списки непрерывных участков кластеров, в которых лежат данные. Файл на четыре килобайта может оказаться resident-записью прямо внутри MFT, а файл на сотни мегабайт раскидан по диску десятками фрагментов. На приёмнике всё повторяется зеркально: создаётся новая запись MFT, выделяются кластеры, прописываются экстенты, обновляются каталоги и журналы. Помимо самих данных переносятся дескрипторы безопасности с ACL, атрибуты (скрытый, системный, архивный, неиндексируемый), временные метки создания и изменения, потоки ADS - alternate data streams, в которых живут, например, метки зоны скачивания Zone.Identifier. Всё это отдельные вызовы, отдельные транзакции в журнал $LogFile, отдельные обороты диска.

Особая статья - метаданные, которые теряются при неаккуратном копировании. Жёсткие ссылки в NTFS - это несколько имён, указывающих на одну запись MFT. Наивный копировщик раскручивает каждое имя независимо и создаёт столько полноценных копий файла, сколько ссылок нашёл: дедупликация хранилища рассыпается, место на целевом диске расходуется в разы быстрее. Точно так же страдают reparse points, символические ссылки и junction-точки, если инструмент не умеет их распознавать. robocopy с флагами вроде /MIR, /COPYALL и /SL переносит владельцев, аудитовские списки и сами ссылки, а не их содержимое, но синтаксис нужно держать в голове, иначе вместо копии получится зеркало с удалёнными лишними файлами - /MIR буквально отражает каталог.

Почему клон грузится, а Ctrl+C нет

Самый наглядный урок различия двух методов - попытка перенести системный диск обычным копированием. Пользователь выделяет диск C целиком, жмёт копировать, вставляет на новый диск, ставит его в машину - и получает мигающий курсор на чёрном экране. Причина в том, что загрузка Windows опирается на вещи, которых нет в видимом дереве каталогов.

На классической схеме BIOS с MBR загрузочный код живёт в первых 446 байтах нулевого сектора диска и в секторах между таблицей разделов и первым разделом. На современных машинах с UEFI загрузчик bootmgfw.efi лежит на отдельном разделе EFI System Partition, отформатированном в FAT32 и помеченном служебным типом GUID. Этот раздел в Explorer вообще не отображается без специальных телодвижений. Рядом обычно отираются MSR, зарезервированный раздел Microsoft, и Recovery-раздел с образом WinRE, которые тоже не назначают себе букву. Реестр загрузки, хранилище BCD, лежит либо в \Boot\Bcd на системном разделе, либо на ESP, и внутри него зашиты ссылки на диски и разделы по их подписям и GUID, а не по буквам. Скопировать файлы - значит получить яйцо без скорлупы: BCD указывает на оборудование и смещения, которых на новом диске в таком виде нет.

Блочный клон решает задачу автоматически, потому что один в один воспроизводит всю адресную структуру: загрузочные сектора сидят на тех же LBA, таблица GPT та же, разделы ESP и Recovery на тех же смещениях, подписи GUID разделов унаследованы. Встроенная проверка подписей Windows при этом честна: две копии с одинаковыми GUID нельзя держать подключёнными одновременно, система сама переведёт дубликат в offline, и это правильно. Файловый перенос системы тоже возможен - так работают sysprep-образы и развёртывание через DISM /Apply-Image - но это уже осознанная процедура с пересозданием загрузочного окружения через bcdboot и bcdedit, а не бытовое копи-паст.

Скорость потока против тысяч мелких файлов

Разница в производительности между методами не вопрос вкуса, а следствие физики. Блочное чтение - это последовательный доступ: головки HDD идут по дорожкам без хаотических прыжков, очередь NVMe заполняется крупными командами, и современный SATA-диск честно выдаёт сто пятьдесят - двести мегабайт в секунду, а NVMe - гигабайты. Даже копирование незанятого места не так уж расточительно, если клонировщик пропускает свободные области по карте кластеров.

Файловое копирование на крупных файлах тоже приближается к скорости потока - видеоархив на десятки гигабайтных роликов уедет сравнимо быстро. Катастрофа случается на мелких объектах. Каталог с сотней тысяч файлов по четыре килобайта превращает перенос в генератор случайных операций: каждый файл - это поиск в индексе каталога, чтение MFT, открытие и закрытие дескрипторов, запись новой записи, обновление журнала, вызов антивирусного фильтра на открытие и на закрытие. На HDD, где случайная операция стоит миллисекунды, итоговая скорость проседает до считанных мегабайт в секунду, а иногда и до сотен килобайт. SSD переживает это легче, но и там накладные расходы на метаданные в разы превышают полезную нагрузку.

Добавляют перца ограничения путей. Классический лимит Win32 - 260 символов MAX_PATH, и до включения поддержки длинных путей через LongPathsEnabled и манифест приложений глубоко вложенные деревья node_modules или резервные копии профилей попросту не копируются: путь обрезается, файл теряется, сообщение об ошибке тонет в середине журнала. robocopy умеет обходить лимит через синтаксис \\?\, Explorer - исторически нет. Практические выводы простые: много мелких файлов выгоднее сначала упаковать в архив одним потоком или переносить блочно, а для файлового режима использовать robocopy с многопоточностью /MT и осмысленными флагами ACL.

Sparse-файлы, VSS и живые системы

Отдельное поле мин - клонирование работающей системы. Пока dd тянет сектора, база данных продолжает писать, страницы подкачки переворачиваются, и клон получается рассогласованным: начало диска соответствует одному моменту времени, конец - другому. Для загрузочного диска это иногда сходит с рук, для базы - почти никогда. Решение в Windows называется VSS, служба теневого копирования: по запросу создаётся снапшот тома, writer-компоненты приложений и самой ОС сбрасывают буферы и замораживают запись на миллисекунды, после чего системная запись уходит через механизм copy-on-write, а клонировщик спокойно читает застывшую точку. Практически все современные средства резервного копирования и миграции построены именно на этом, и отключенная служба VSS - классическая причина ошибок вида snapshot creation failed.

Sparse-файлы добавляют тонкости с обеих сторон. Разрежённый файл в NTFS занимает мало физического места, но его нулевые диапазоны не хранятся на диске. Блочный клон переносит устройство как есть и автоматически сохраняет разреженность - нули это нули. Файловый копировщик без специальных флагов честно прочитает все виртуальные нули и выпишет их на приёмнике реальными кластерами: файл в сто гигабайт логического размера раздуется со своих пяти физических до полной величины. rsync умеет --sparse, robocopy отдельного флага не предлагает, и про это стоит помнить при переносе дисков виртуальных машин в форматах вроде динамических VHD.

SSD, TRIM и диски меньшего размера

Твердотельные накопители вносят свой корректив в выбор метода. Блочная копия затаптывает целевой SSD целиком, включая области, которые на источнике пусты: контроллер получает лишние гигабайты записи, расходуется ресурс циклов перезаписи, а свободные блоки исчезают из пула, доступного сборке мусора. Аккуратные клонировщики после копирования отправляют на пустые диапазоны команды TRIM (для SATA) или dataset management (для NVMe), помечая сектора освобождёнными; некоторые идут дальше и пропускают при копировании диапазоны, занятые сплошными нулями, заодно выполняя их отброску. Проверить, работает ли TRIM в системе, можно командой fsutil behavior query DisableDeleteNotify - ноль означает, что механизм активен.

И наконец, сценарий, где файловое копирование выигрывает безоговорочно: переезд на диск меньшего объёма. Типовой апгрейд - замена старого HDD на сотню гигабайт заполненных данных на компактный SSD. Блочный клон физически требует целевой носитель не меньше исходного, потому что разделы размечаются по тем же LBA-адресам. Обходные пути существуют - сначала ужать раздел средствами diskmgmt.msc до размеров нового диска, потом клонировать - но сжатие упирается в неперемещаемые файлы, MFT-зону и так далее. Файловое развёртывание лишено этого ограничения принципиально: разделы на новом диске размечаются под его геометрию, образ прикладывается через DISM, загрузчик пересоздаётся через bcdboot, и система оказывается на маленьком быстром диске без единого байта мёртвого места. Именно поэтому современные инструменты миграции внутри себя комбинируют оба мира: разметку и загрузочные структуры делают по-блочному, а данные разделов кладут пофайлово, получая гибкость без потери загрузочности.

Понимание того, какой метод работает под капотом конкретной утилиты, экономит часы. Клон - когда нужна точная копия устройства, загрузочность без вопросов и полнота вплоть до удалённых файлов. Файлы - когда размер цели меньше, структура меняется, а часы работы важнее церемониальной идентичности.