Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Изменение строк в больших файлах 
V
    Опции темы
ColdSpirit
Дата 19.6.2014, 10:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 10.12.2010

Репутация: нет
Всего: 2



Есть огромный текстовый файл, нужно изменить строку, допустим, в центре файла, каким образом лучше и бытрее всего это сделать?

Пока придумалось 3 варианта:
1. Загрузить весь файл в память, изменить где нужно, записать.
2. Сместить "хвост" файла (что после строки) на определенное количество байт, записать до хвоста нужное).
3. Записать второй файл на выходе (читаю один - меняю где надо - пишу другой).

Пока мне самым оптимальным кажется 3й вариант
PM MAIL   Вверх
Akina
Дата 19.6.2014, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 20
Всего: 454



Реально оптимальным имхо следует считать разбиение избыточно большого файла на части.
Что же до оптимальности приведённых вариантов... первые два суть одно и то же (но второй получше будет), третий же заведомо худший. Чтобы это понять, достаточно разобрать, как будет выполняться операция на уровне обработчика (файловая система) - (физический носитель).
Оптимальным же я считаю вариант загрузки "хвоста" в память, добавление в начало буфера чтения нужной информации, и затем сброс на диск в существующий файл с заданной позиции. При этом не будет выполняться перезапись начал файла до изменяемого участка.

Т.е. формализованно это так:
Код


open file
position = find()
buffer = read(from position to eof)
seek position
write(additions)
write(buffer)
close file



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
ksnk
Дата 19.6.2014, 11:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 7
Всего: 386



Если файл "реально большой", то, вероятнее всего, проблематично будет хранить его в памяти. Можно делать так
- переместить указатель на конец изменения
- скопировать конец файла во временный файл
- переместить указатель на начало изменения 
- отрезать файл по этому указателю
- дописать изменение
- скопировать хвост из временного файла.
- удалить временный файл.

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


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Akina
Дата 19.6.2014, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 20
Всего: 454



Если "хвост" не помещается в память - да, придётся выполнять перезапись блоками, начиная от хвоста файла и двигаясь к точке вставки.

А временный файл - гарантированные потери в скорости работы.



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
ColdSpirit
Дата 19.6.2014, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 10.12.2010

Репутация: нет
Всего: 2



Цитата(Akina @  19.6.2014,  11:00 Найти цитируемый пост)
Оптимальным же я считаю вариант загрузки "хвоста" в память, добавление в начало буфера чтения нужной информации, и затем сброс на диск в существующий файл с заданной позиции.

Мне кажется, что это второй вариант, только тут сначала запись нужной информации куда нужно, а потом запись остального, но в памяти конечно хранить хвост не оптимально. Если сначала в файле расчистить место под нужные данные, а потом записать на них, в память хвост загружать не придется, вопрос в другом - сколько времени займет перемещение хвоста "на пару байт вправо"?

Akinaksnk, где можно поподробнее почитать про буфера?

А если изменений несколько или чуть ли не весь файл? Думаю похоже на систему контроля версий, она ищет места где добавить и записывает туда. Вот только не пользовался ни разу, может ошибаюсь, и алгоритма работы не знаю.
Еще четвертый вариант - держать изменения допустим в памяти или временном файле, а потом записать целиком, вопрос как записать быстро)
PM MAIL   Вверх
ksnk
Дата 19.6.2014, 14:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 7
Всего: 386



ColdSpirit, Уточни, что такое "изменение"? Допустим, что это массив структур {x:смещение в оригинальном файле, l:длина изменяемого куска, lt: длина измененного куска,  txt: измененный кусок}. Отсортирован по смещению.

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




--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
ColdSpirit
Дата 19.6.2014, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 10.12.2010

Репутация: нет
Всего: 2



Цитата(ksnk @  19.6.2014,  14:18 Найти цитируемый пост)
Допустим, что это массив структур {x:смещение в оригинальном файле, l:длина изменяемого куска, lt: длина измененного куска,  txt: измененный кусок}. Отсортирован по смещению.

Типа того, только txt не нужен думаю, при необходимости его всегда можно из оригинального файла считать.

Думаю так пока и сделаю, Akinaksnk, благодарю вас.
Если появятся какие идеи - буду рад услышать =)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.0692 ]   [ Использовано запросов: 20 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.