![]() |
|
![]() ![]() ![]() |
|
ColdSpirit |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 95 Регистрация: 10.12.2010 Репутация: нет Всего: 2 |
Есть огромный текстовый файл, нужно изменить строку, допустим, в центре файла, каким образом лучше и бытрее всего это сделать?
Пока придумалось 3 варианта: 1. Загрузить весь файл в память, изменить где нужно, записать. 2. Сместить "хвост" файла (что после строки) на определенное количество байт, записать до хвоста нужное). 3. Записать второй файл на выходе (читаю один - меняю где надо - пишу другой). Пока мне самым оптимальным кажется 3й вариант |
|||
|
||||
Akina |
|
|||
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 20 Всего: 454 |
Реально оптимальным имхо следует считать разбиение избыточно большого файла на части.
Что же до оптимальности приведённых вариантов... первые два суть одно и то же (но второй получше будет), третий же заведомо худший. Чтобы это понять, достаточно разобрать, как будет выполняться операция на уровне обработчика (файловая система) - (физический носитель). Оптимальным же я считаю вариант загрузки "хвоста" в память, добавление в начало буфера чтения нужной информации, и затем сброс на диск в существующий файл с заданной позиции. При этом не будет выполняться перезапись начал файла до изменяемого участка. Т.е. формализованно это так:
-------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
ksnk |
|
|||
![]() прохожий ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 6855 Регистрация: 13.4.2007 Где: СПб Репутация: 7 Всего: 386 |
Если файл "реально большой", то, вероятнее всего, проблематично будет хранить его в памяти. Можно делать так
- переместить указатель на конец изменения - скопировать конец файла во временный файл - переместить указатель на начало изменения - отрезать файл по этому указателю - дописать изменение - скопировать хвост из временного файла. - удалить временный файл. Вероятно, наиболее быстро - без временного файла. Просто читать файл буферами, бОльшими по размеру, чем размер изменяемого фрагмента, менять буфер, сдвигая туда-сюда и прописывать "на старое место" измененный кусок. Вторым буфером можно скачать В конце файла придется либо отрезать ненужное, либо дописать нужное. -------------------- Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! ![]() |
|||
|
||||
Akina |
|
|||
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 20 Всего: 454 |
Если "хвост" не помещается в память - да, придётся выполнять перезапись блоками, начиная от хвоста файла и двигаясь к точке вставки.
А временный файл - гарантированные потери в скорости работы. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
ColdSpirit |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 95 Регистрация: 10.12.2010 Репутация: нет Всего: 2 |
Мне кажется, что это второй вариант, только тут сначала запись нужной информации куда нужно, а потом запись остального, но в памяти конечно хранить хвост не оптимально. Если сначала в файле расчистить место под нужные данные, а потом записать на них, в память хвост загружать не придется, вопрос в другом - сколько времени займет перемещение хвоста "на пару байт вправо"? Akina, ksnk, где можно поподробнее почитать про буфера? А если изменений несколько или чуть ли не весь файл? Думаю похоже на систему контроля версий, она ищет места где добавить и записывает туда. Вот только не пользовался ни разу, может ошибаюсь, и алгоритма работы не знаю. Еще четвертый вариант - держать изменения допустим в памяти или временном файле, а потом записать целиком, вопрос как записать быстро) |
|||
|
||||
ksnk |
|
|||
![]() прохожий ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 6855 Регистрация: 13.4.2007 Где: СПб Репутация: 7 Всего: 386 |
ColdSpirit, Уточни, что такое "изменение"? Допустим, что это массив структур {x:смещение в оригинальном файле, l:длина изменяемого куска, lt: длина измененного куска, txt: измененный кусок}. Отсортирован по смещению.
буфер - кусок памяти разумного размера. Нужно посчитать минимально допустимый размер, чтобы алгоритм не глючил. Основной смысл - читаем кусочек оригинального файла в буфер, делаем в памяти изменения и пишем с той же позиции новое содержимое. Сдвигаемся по файлу на размер буфера - читаем,делаем изменения,пишем и т.д. Нужно, конечно, подсуетиться и сохранить затираемую такой операцией часть данных в еще одном буфере, например. -------------------- Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! ![]() |
|||
|
||||
ColdSpirit |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 95 Регистрация: 10.12.2010 Репутация: нет Всего: 2 |
Типа того, только txt не нужен думаю, при необходимости его всегда можно из оригинального файла считать. Думаю так пока и сделаю, Akina, ksnk, благодарю вас. Если появятся какие идеи - буду рад услышать =) |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Алгоритмы" | |
|
Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Алгоритмы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |