Мне было поручено написать программу сбора данных для 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?