Этим утром я потерял кучу файлов, но, поскольку том, которым они были, был дефрагментирован как внутри, так и снаружи, доступна вся информация, необходимая для 100% восстановления; Мне просто нужно заполнить FAT, где это необходимо.
Я написал для этого программу и проверил ее на копии FAT, которую я сбросил в файл, и она отлично работает, за исключением того, что для некоторых файлов (17 из 526) цепочка FAT слишком длинна — один кластер и, таким образом, сшиты со следующим файлом.
К счастью, я точно знаю, в чем проблема. я использовал ceil
в моем расчете EOF, потому что даже один байт потребует целый дополнительный кластер:
//Cluster is the starting cluster of the file
//Size is the size (in bytes) of the file
//BPC is the number of bytes per cluster
//NumClust is the number of clusters in the file
//EOF is the last cluster of the file’s FAT chain
DWORD NumClust = ceil( (float)(Size / BPC) )
DWORD EOF = Cluster + NumClust;
Этот алгоритм работает отлично для всех, кроме файлов, размер которых в точности кратен размеру кластера, и в этом случае они оказываются слишком большими.
Я думал об этом некоторое время, но не знаю, как это сделать. Кажется, что это должно быть просто, но как-то это удивительно сложно.
Какая формула подойдет для файлов любого размера?
возможно ceil( (float)((Size - 1) / BPC) )
?
Если бы все было целым типом, даже лучше было бы ((Size - 1) / BPC) + 1
,
Если вы хотите, чтобы количество кластеров было бы (size + BPC - 1) / BPC
со всеми интегральными типами данных.
ceil( (float)(Size / BPC) )
делает целочисленное деление, затем бросает это, чтобы плавать.
Тебе нужно ceil( (float)Size / BPC )
сделать это правильно. Но использование поплавков здесь кажется плохой идеей … Смотрите другие ответы для целочисленного решения.