Как втиснуть данные в середину файла?

Тема в разделе "WASM.HEAP", создана пользователем Green_DiCk, 2 июн 2008.

  1. Green_DiCk

    Green_DiCk New Member

    Публикаций:
    0
    Регистрация:
    8 июл 2007
    Сообщения:
    338
    Вроде бы задачка тривиальная, но я с удивлением обнаружил, что у меня не хватает мозгов ее решить. Итак, как записать данные в середину файла, а нижележащие данные сдвинуть вниз? Разумеется корявым образом я это сделать могу, но не хочется. А как правильно - хз. И если возможно, то без мэппингов, так как должно быть покроссплатформеннее. Спасибо.
     
  2. Exp10der

    Exp10der Мастер дзена

    Публикаций:
    0
    Регистрация:
    27 авг 2007
    Сообщения:
    337
    Адрес:
    Красноярск
    Читай файл с конца по блокам и записывай по адресу начало_текущего_блока+размер_вставляемых_данных, когда дойдёшь до нужной позиции просто запиши свои данные и всё.
     
  3. det

    det New Member

    Публикаций:
    0
    Регистрация:
    31 янв 2007
    Сообщения:
    31
    а формат файла какой, PE?
     
  4. Green_DiCk

    Green_DiCk New Member

    Публикаций:
    0
    Регистрация:
    8 июл 2007
    Сообщения:
    338
    Exp10der
    )) Честно прочитал раз 10. Ни черта не понял. Но потом дошло. Спасибо. Только пока не догнал как читать с конца и в каком режиме в этом случае открывать файл? fopen(..., "r+")?

    det
    Да не. обычный файл - бинарный или текстовый. скорее всего текстовый.
     
  5. device

    device Reflection

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    1.198
    Адрес:
    RF
     
  6. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    как бы этот код не верен. Надо записать данные, предварительно сдвинув данные, лежащие после.
    В чем трудность?
    Читаем из файлы конечный блок, двигаем файловый указатель на "куда записать + размер записываемого". и записываем конечный блок. После этого возвращаемся на "куда записать", и пишем то что нужно.
     
  7. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    n0name
    А если указатель "зашкаливает" за границу файла?
     
  8. Green_DiCk

    Green_DiCk New Member

    Публикаций:
    0
    Регистрация:
    8 июл 2007
    Сообщения:
    338
    device
    Эммм... ну и че этто будет? разве данные в середине не потрутся? (а "середина" это я условно сказал)) имеется в виду не начало и не конец.) а вот ф-цию fstat я не знал раньше. сэнкс.
     
  9. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
     
  10. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    n0name
    А я вот что прочитал (до конца)
     
  11. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    После lseek() нужно вызвать SetEndOfFile() и место реально выделится.
    P.S. Не знаю, если ли аналоги в C'шной бибилиотеке, т.к. никогда ей не пользовался.
     
  12. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    Xerx
    Проблему в этом случае видимо решит запись в конец файла недостающих байтов (например, запись байта 0 в нужном количестве).
     
  13. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    SetEndOfFile выделяет доп. место от конца файла и до текущей позиций файлового указателя. Причем заполняет все нулями.

    p.s. Так я и не в свое время разобрался, как можно просто изменить размер файла без инициализации.
     
  14. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Я тоже это читал.
    А в чем проблема-то? Или ты про "but this does not change the size of the file". Так у меня в мане такого нет. Причем в разных *nix дистрибах. Смотрел на Debian и на солярке десятой.
     
  15. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    а что стоит переписать начиная с конца файла сперва блок длиной с вставляемый двигаясь вперед. Затем начиная с бывшего конца файла оставшееся двигаясь назад. Затем уже в позицию вставки записать то, что врезать надо?
     
  16. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    в общем виде задача не имеет вменяемого решения, т.к. все зависит от длины файла, fs и носителя, а так же свободного места на носителе, где размещен файл, объема памяти и наличия дополнительных носителей.

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

    да много тонкостей. более или менее универсальное решение представляет собой совокупность функций, выбираемых в зависимости от конкретных обстоятельств, например, того же размера файла, например.
     
  17. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.242
    здесь ещё многое зависит от структуры самого файла - с деревом общаться по дописыванию и вставки
    узлов довольно легко
    Green_DiCk
    так что подумай насчёт подборки удобного формата.
     
  18. device

    device Reflection

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    1.198
    Адрес:
    RF
    Извините, я был не внимателен, данные не потрутся, а просто новые данные впишутся в середину.