Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C++ Builder > Управление данными в TMemoryStream |
Автор: MuadDib 24.9.2007, 07:31 | ||||
Здравствуйте, уважаемые. Возникла потребность работать с большими объемами данных помещенных в TMemotyStream объект. К примеру с большими файлами, загруженными в поток памяти. Необходимо удалять из памяти определенным образом помеченные блоки и соответствующим образом корректировать размер потока памяти. Для работы с потоком памяти помимо его стандартных средств исползую указатель на его данные: код условно-описательный, чтобы показать, что делаю:
Данных код нормально работает, с файлами не слишком большого размера. С большими файлами - очень медленно. Еще вариант, тоже условно-описательный:
Данных код тоже работает нормально с файлами не слишком большого размера. С большими файлами медленно, хотя и быстрее чем предыдущий. Подскажите пожалуйста, как еще можно реализовать данную задачу с наибольшим быстродействием. Интересует именно быстродействие, затраченные ресурсы неважны. Заранее спасибо! |
Автор: MuadDib 24.9.2007, 09:34 |
Если все записи одинакового размера, то почему бы не перемещать на место удалённой записи самую последнюю запись из "хвоста". Добавлено через 4 минуты и 58 секунд Дело в том, что данные в потоке должны следовать в том порядке, в котором они были туда загружены, менять последовательность нельзя. Т.е. на место удаленного блока должен вставать следующий непомеченный к удалению блок. Размер выделенной памяти действительно можно изменять не каждый раз, а только единожды после всех операций по перемещению данных, как это сделано во втором примере, однако это не дает ощутимого результата. |
Автор: Mihhail 24.9.2007, 11:09 | ||||
Я имею в виду не изменять размер даже в этом случае. Освобождать память только при завершении программы. А по алгоритму могу предложить следующее:
Время перемещения всех записей всё равно не уменьшить, но можно сделать что бы программа не зависала, т.е. не перемещать все записи за раз. А создавать отдельный поток или просто таймер, который через небольшие промежутки времени смещает блоки небольшой длины(поэксперементировать с их размером). Пока единственное что приходит в голову.... Добавлено через 3 мин А если забить на это перемещение? Нам же известны номера удалённых записей, при просмотре просто перескакивать через них. |
Автор: Alexeis 24.9.2007, 11:50 | ||
Перед тем как придумывать определите какие файлы являются большими и каких ресурсов не жалко. Все таки файлы бывают и 100Гб, а в ОЗУ выделить непрерывный блок в 1Гиг порой невозможно. |
Автор: Vyacheslav 24.9.2007, 12:09 |
А зачем в приницпе держать это все в TMemotyStream постоянно? А если уж это так нужно, то почему не использовать вектор объектов TMemotyStream? |
Автор: MuadDib 24.9.2007, 12:14 |
Если вывести упаковку в отдельный поток на длительное время (т.к. файл размером, например 200 МБ будет паковаться достаточно долго) , получится, что работать с данными будет все равно нельзя, так как они будут постянно изменяться и не будут актуальны. Это получится как работа с реляционной БД в отсутствии транзакций - не знаешь есть ли физически запись в потоке с которой собираешься работать или нет ее и подобные проблемы. Забить тоже нельзя, т.к. смысл упаковки в том, чтобы в конечном итоге уменьшить размер конечного потока и сохранить его в файл. Т.е. ресурсозатраты неважны на этапе работы с потоком, но затем файл, сформированный в итоге должен занять возможный минимум дискового пространства. Такая вот неприятная штука получается... Нужно и с елки съехать и, желательно, седалище не оцарапать |
Автор: MuadDib 24.9.2007, 12:39 |
Если не затруднит, хотелось бы попросить Ермолаева Вячеслава привести пример корректного создания вектора объектов TMemoryStream и работы с ним. Дело в том, что по-моему вариант: vector <TMemoryStream *> не слишком подходит. Желательно, как мне кажется, хранить не указатели, а сами потоки. И т.к. я не имею большого опыта работы с векторами не соображу как сделать верно... Хотя идея такая тоже приходила. |
Автор: Alexeis 24.9.2007, 12:40 | ||
Предлагаю такой алгоритм. Сначала расчитать где должна быть каждая из записей, затем выделить новый блок нужной длинны и за один проход скопировать каждый блок строго на свое место. скопировать 200Мб в памяти это довольно быстро, должно быть не более 1й секунды. Добавлено через 1 минуту и 48 секунд
TMemoryStream - это клас VCL, потому не может быть статическим. |
Автор: MuadDib 24.9.2007, 12:49 |
Alexeis, я заню, что TMemoryStream не может быть статическим. А предложенный алгоритм начинаю писать, по-моему дельно, нужно пробовать... |
Автор: Vyacheslav 24.9.2007, 14:48 | ||||
Кстати как раз удобнее во всех случаях хранить указатели. Сэкономите на копировании. Если информацию, удалять-не удалять можно выудить из самого содержимого, то весь Ваш код по сжатию уложится в строкe плюс небольшая модификация CheckDelRecord( пишу по памяти без среды, поэтому могут быть ошибки )
|
Автор: MuadDib 25.9.2007, 13:30 |
Всем спасибо, получилос сделать через вектор быстро и удобно. |