Сжатие или частичное усечение файла в DOS / FAT - PullRequest
4 голосов
/ 20 мая 2010

Мне было поручено написать программу сбора данных для Unitech HT630 , которая работает под управлением проприетарной операционной системы DOS, которая может запускать исполняемые файлы, скомпилированные для 16-битной MS DOS, с некоторыми ограничениями. Я использую компилятор Digital Mars C / C ++, который до сих пор работает хорошо.

Одним из требований приложения является то, что файл данных должен быть простым для чтения человеком, что означает, что файл может быть импортирован в Excel или открыт с помощью Блокнота. Я использую формат записи переменной длины, очень похожий на CSV, который я успешно реализовал, используя функции ввода-вывода файла стандартной библиотеки C.

При сохранении записи я должен вычислить, больше или меньше обновленная запись, чем версия записи, которая в настоящее время находится в файле данных. Если оно больше, я сначала сдвигаю все записи сразу после текущей записи на разность размеров, рассчитанную перед сохранением обновленной записи. EOF автоматически расширяется ОС для размещения дополнительных данных. Если меньше, я сдвигаю все записи назад на мое вычисленное смещение. Это работает хорошо, однако я не нашел способа изменить маркер EOF или размер файла, чтобы игнорировать данные после окончания последней записи.

В большинстве случаев размер записей будет увеличиваться, поскольку программа сбора данных будет заполнять некоторые пустые поля данными при сохранении записи. Размеры записей уменьшаются только при внесении исправлений в существующую запись или при сохранении обычной записи, если описательные данные в записи длиннее, чем программа читает в памяти.

В случае сжимающейся записи, после последней записи в файле я остаюсь с теми данными, которые были там до смены. Я записывал в файл разделитель EOF после «сжатия записи», чтобы указать, где находится конец моих записей, и заполнил оставшиеся данные, но у меня больше нет чистого файла до «сохранения растущей записи». расширяет размер файла по заполненной пробелом области. Функция truncate() в unistd.h не работает (сейчас я думаю, что это только для * nix-ароматов?).

Одно предложенное решение, которое я видел, включает создание второго файла и запись всех данных, которые вы хотите сохранить в этот файл, а затем удаление оригинала. Поскольку у меня есть только 4 МБ дискового пространства для использования, это работает, если размер файла меньше 2 МБ минус размер исполняемого файла моей программы и файлов конфигурации, но в противном случае произойдет сбой. Весьма вероятно, что когда это начнется, пользователи получат файл размером более 2 МБ.

Я посмотрел на Список прерываний Ральфа Брауна и ссылку на прерывание в IBM PC Assembly Language and Programming , и я не могу найти что-либо, чтобы обновить размер файла или аналогичный.

Возможно ли уменьшение размера файла без создания второго файла даже в DOS?

Ответы [ 2 ]

4 голосов
/ 20 мая 2010

Чтобы уменьшить размер файла в DOS, вы стремитесь к точке усечения с помощью int 21 (ax=4200h, bx=handle, cx:dx=offset) и вызываете запись с нулевой длиной: int 21 (ax=4000h, bx=handle, cx=0 (имеется ввиду усечение))

0 голосов
/ 20 мая 2010

В качестве альтернативы смещению записей при изменении размера записи вы можете завершить каждую запись полем «pad», которое дополняет ее до стандартного размера (например, с пробелами или аналогичным).

...