nixp.ru v3.0

25 мая 2017,
четверг,
23:17:05 MSK

DevOps с компанией «Флант»
anonymous написал 8 апреля 2006 года в 23:25 (212 просмотра) Ведет себя неопределенно; открыл 1814 темы в форуме, оставил 5575 комментариев на сайте.

Есть открытый через open файл, в нём текст:

AAAABBBB

.

Как проще всего туда вставить CCCC, чтоб получилось следующее:

AAAACCCCBBBB

?

Прогаю на си, можно использовать стандартную библиотеку и glib.

Мне ничего в голову, кроме как писать в другой файл, а потом его переименовать, не приходит. Найти позицию AAAA можно с помощью lseek.

Code Monkey

читаешь строку в память, заменяешь как тебе надо и пишешь обратно в фаил. как это делается тебе подскажет инет и/или книги

anonymous

Если они одной длины, то всё понятно.

А если разной?

Как сдвигать?

anonymous

Сперва не понял твой ответ.

Я же не просто так тебя спрашиваю.

Если файл длинный очень.

Не загружая всё в память.

Feuerbach

Ну можно, наверное, как-то извертеться и работать только с одним файлом, но смысл? Имхо, вариант с переименованием проще всего.

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

rgo

делать так же как работает memmove, только с файлом. прочитал n байт с конца, то есть по смещению seek (fd, N-n, SEEK_SET), и записал по смещению seek (fd, N-n+strlen(«CCCCCC»), SEEK_SET), потом читаем с N-2*n а записываем в N-2*n+strlen(«CCCCCC»), и тд, и тп.

хотя можно и в прямом направлении, надо только два буфера чтения иметь, seek’ов буде поменьше, но по-моему это компенсируется дополнительным write. Итерация будет выглядеть примерно так: читаешь в первый буфер n байт, seek (fd, -n, SEEK_CUR), записываешь strlen(«CCCCCC») байт из второго буфера, а затем n-strlen(«CCCCCC») из первого. После чего меняем буферы местами, и следующая итерация.

Если совсем поизвращаться охота, то твой выбор mmap: мапишь файл в оперативку и memmove. Только если размер файла выражается в гигабайтах, то придётся мапить кусочками, вручную обрабатывая все эффекты на стыках. Хотя если платформа 64-bit, я думаю сложно будет найти такой файл кот, не влезет в адресное пространство.

[add]

N — это исходный размер файла, если кто не понял.

а n — просто константа, напр, 4096.

anonymous

Большое спасибо!

Longobard

А можешь замапить его в буфер mmap-ом и дальше мучать, будет проще.

Feuerbach

rgo про это уже писал.

Longobard
Feuerbach
rgo про это уже писал.

Сорри, не заметил :)

А почему rgo называет это извратом? Имхо mmap красивое и удобное средство. Замапил файлик в чаровский буфер, дальше ковыряешь его как строку, и все.

rgo
А почему rgo называет это извратом?

ну просто.

1) изврат и всё тут. когда возникают вопросы по использованию lseek, надо учится пользоватся lseek’ом.

2) как я уж сказал, 4Gb файлик на 32битном пне, придётся двигать в три приёма, как минимум, точнее не могу сказать, дела не имел с ними. То есть не меньше возиться придётся

3) а если файлик bzip’ом пожат, что делать будешь? в случае классических open/read/write/lseek/close, можно воспользоваться popen, а с mmap’ом без libbz2.so будет совсем нехорошо.