Сжатие - это удаление избыточности из данных. К сожалению, маловероятно, что избыточность будет распределена с монотонной равномерностью по всему файлу, и это единственный сценарий, в котором можно ожидать сжатия и детального произвольного доступа.
Однако вы можете закрыть для произвольного доступа, сохранив внешний список, созданный во время сжатия, который показывает соответствие между выбранными точками в несжатом потоке данных и их местоположениями в сжатом потоке данных. Очевидно, вам придется выбрать метод, при котором схема трансляции между исходным потоком и его сжатой версией не зависит от местоположения в потоке (т.е. без LZ77 или LZ78; вместо этого вы, вероятно, захотите перейти к Хаффману или байту. парное кодирование.) Очевидно, что это повлечет за собой много накладных расходов, и вам нужно будет решить, каким образом вы хотите обменяться между пространством хранения, необходимым для «точек закладки», и временем процессора, необходимым для распаковки потока, начиная с отметка в закладке, чтобы получить данные, которые вы на самом деле ищете, для этого чтения.
Что касается записи с произвольным доступом ... это почти невозможно. Как уже отмечалось, сжатие заключается в удалении избыточности из данных. Если вы попытаетесь заменить данные, которые могли быть и были сжаты, потому что они были избыточными, на данные, которые не имеют такой же избыточности, они просто не будут соответствовать.
Однако, в зависимости от того, сколько записи с произвольным доступом вы собираетесь выполнить, вы можете смоделировать ее, поддерживая разреженную матрицу, представляющую все данные, записанные в файл после сжатия. При всех чтениях вы проверяете матрицу, чтобы увидеть, читали ли вы область, в которую вы записали после сжатия. Если нет, то вы перейдете к сжатому файлу для данных.