Перемещение между двумя точками в выходном файле - PullRequest
1 голос
/ 17 июля 2009

Я пишу программу на C, которая создает большой выходной файл. Чтобы повысить удобочитаемость, я хотел бы собирать определенные виды выходных данных в определенных точках файла, а не разбрасывать их случайным образом.

Рассмотрим файл вроде:

log
log
(a)

output
output
output(b)

Скажите, что программа в данный момент пишет строку в (b). Есть ли в C особенно элегантный способ добиться эффекта перехода в точку (a), добавления линейного выхода и затем возобновления нормального вывода в (b)?

Я знаю, что мог бы добиться этого эффекта, используя стандартные инструменты оболочки, такие как csplit, чтобы разбить файл в указанной точке, добавить вывод в первую половину, а затем объединить его. Однако это приложение должно быть кроссплатформенным, поэтому я не могу рассчитывать на наличие оболочки.

Любые предложения будут наиболее полезны!

Ответы [ 5 ]

6 голосов
/ 17 июля 2009

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

Вы не можете просто вставить в файл, перемещая содержимое над точкой вставки, чтобы освободить место. Это просто не концепция, которую поддерживают обычные файловые системы. Вам нужно было бы физически прочитать и переписать все «выходные» фрагменты, чтобы вставить «журнальный» фрагмент, что потребовало бы все больших объемов работы по мере роста файла.

Лучше всего было бы написать два отдельных файла, а затем соединить их вместе в конце.

Редактировать после комментария Шарпи: Поскольку вывод представляет собой набор команд для программы, значит ли это, что вы можете смело предполагать, что он никогда не будет больше пары МБ, и просто встроить его в память перед тем, как записать все за один раз?

4 голосов
/ 17 июля 2009

Вы не можете сделать это напрямую по очень простой причине:

Нет способа вставить байты в середину файла. Вы можете только перезаписать часть файла или добавить в конец файла.

Если вы хотите вставить в середину файла, у вас есть два варианта:

  • Считайте все байты после позиции, в которую вы хотите вставить в память. Затем запишите фрагмент, который вы хотите вставить, затем запишите все байты, которые вы кэшировали в память. В результате байты вставляются в заданную позицию за счет произвольно большого блока памяти для удержания фрагмента, который нужно «оттолкнуть».
  • Кроме того, вы пишете все в новый файл. Скопируйте байты из исходного файла в новый файл. Если вы находитесь в точке, где вы хотите вставить свои новые данные, напишите новую строку. Затем продолжайте копирование из исходного файла, пока не закончите. Это работает без необходимости, возможно, большого куска памяти, но требует использования временного файла, в котором вы сохраняете объединенный результат.

...

  • В качестве альтернативы, альтернативно, не записывайте свои выходные данные непосредственно в файл, но сохраняйте все в памяти и записывайте их упорядоченно в выходной файл, как только вы закончите сбор строк журнала.
2 голосов
/ 17 июля 2009

Это очень необычное требование.

Одним из способов будет префикс дифференцирующей строки для двух видов выходные строки, а затем записать их в тот же файл. Если вам нужен определенный набор выходов, grep для них в объединенном файле.

output.txt ...
MARK1: журнал
MARK2: выход
MARK1: журнал
MARK2: выход
MARK2: выход

grep "^MARK1:" output.txt
grep "^MARK2:" output.txt

В конечном итоге вам понадобится файл, как вы и хотели, чтобы он был записан.
Для этого вам нужно будет отрубить строки префикса.
В то время было бы очень легко, если бы вы использовали строки, соответствующие простому regex
Что-то вроде

sed 's/^MARK.://g' output.txt > filtered.txt
0 голосов
/ 17 июля 2009

C или C ++?Если C ++, вы можете использовать seekp () для позиционирования выходного указателя.Это только позволит вам перезаписать.

0 голосов
/ 17 июля 2009

с помощью fgetpos вы можете сохранить указатель на позицию в файле и перейти к ней в любое время с помощью fseek :

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...