187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
|
|||||||||||
1 | |||||||||||
Удалить записанный экземпляр класса из двоичного файла24.10.2012, 07:18. Показов 2614. Ответов 34
Метки нет (Все метки)
Задача - удалить записанный экземпляр класса из дв. файла.
(В моём решении, удаленный экземпляр просто затирается последним)
Отчего такая феерическая ошибка? Может ли быть так, что, когда я сделал fseek на последнюю запись и считал её (ушел в EOF), то как-то нарушил всю суть работы? Хотя PrintFile после возврата каретки на текущую запись всё же отработал D: Добавлено через 6 минут Вместо X-ACTION можно вставить и такое. Тоже поможет :
0
|
24.10.2012, 07:18 | |
Ответы с готовыми решениями:
34
Можно ли считывать поля класса из двоичного файла одним fread Создать экземпляр одного класса в Main, и передать его в экземпляр другого класса Удалить экземпляр класса в массиве Сборщик мусора (как удалить экземпляр класса) |
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
|
|
29.10.2012, 23:04 | 21 |
В предыдущих постах ты пишешь: это помогает, то помогает... То есть, решение проблемы у тебя есть? Просто хочешь знать, почему возникает ошибка? Или нет решения?
Эту причину нешёл. После записи сделай fflush(FILE *f) . Запись в буфер идёт и нужно, чтобы изменения (перед чтением) попали в файл. И насчёт конца файла. Проверь, правильно ли читаешь последний объект в файле. Как у тебя чтение сделано не видно, но если читать с начала объекта, и читать количество байтов, равное размеру объекта, то признак конца файла не установится. Установится, если чтение сделано именно до конца файла, или начато не с той (большей) позиции.
1
|
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
|
|
30.10.2012, 06:50 [ТС] | 22 |
alsav22, Т_Т.. А ведь я же проверял fflush.. Видать я его перед считыванием ставил и почему-то так не срабатывало. Поставил после PrintFile и теперь всё в порядке.
Можете пояснить, почему это помогло? Ведь, если запись идет в буфер, то нам все равно не важно это, так как fread так же читает из буфера, а не из файла, разве нет?
0
|
26 / 26 / 3
Регистрация: 20.09.2011
Сообщений: 68
|
|
30.10.2012, 07:56 | 23 |
Ты немного не про тот буфер думаешь. буфер записи на винчестер. система кэширует данные в буфере для ускорения операций чтения записи данных. после того как ты записал данные в файл(точнее даже в дескриптор) они пишутся в буфер записи на винчестер. через какое-то время они запишутся физически на диск, не ранее. можно самому эту синхронизацию вызвать через fflush, а можно просто подождать, например через паузу. а буфер чтения это уже другое. поэтому ты и не можешь читать напрямую из буфера, в который ты записал данные. примерно так. это касательно Linux\Unix. хотя и в виндовс скорее всего тоже самое.
1
|
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
|
|
30.10.2012, 16:49 | 24 |
Нет, сам не понимаю. Думаю, тут дело в том, что файл открыт одновременно для записи и чтения. Как в таком случае буфер организован, без понятия. Самое интересное в том, что тут не просто чтение неправильно происходит, но и запись в файл, в результате, получится неправильная. Чтение сдвигает курсор для записи? Ещё помогает, если после записи просто указать (через fseek()) откуда читать.
1
|
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
|
||||||
30.10.2012, 17:05 [ТС] | 25 | |||||
alsav22, я делал так, как будто fread и fwrite имеют общую позицию в файле, то есть, если мы прочитали первую запись fread, то, испоьзовав после неё fwrite, писать начнет со второй записи. Так оно и происходило, разве что fread колбасило. fwrite отрабатывало корректно. Проверял ручками дв. файл, байты нормальные.
Поставил везде fflush и всё заработало так, как нужно. Ну как везде.. Если есть чтение - не ставлю. Если есть запись - ставлю ТОЛЬКО после последнего блока. Если есть пара блоков чтения и записи, и они между собой перекликаются, ставлю перед каждым чтением. Пример :
kertio, если честно, ничего не понял : ) Постараюсь разобраться чуть позже. Есть ли у тебя ссылка, где можно почитать о таком? Я раньше никогда fflush не использовал и все работа корректно. Подобных ошибок, как у меня, у кого-то ещё в google не нашел..
0
|
26 / 26 / 3
Регистрация: 20.09.2011
Сообщений: 68
|
|
30.10.2012, 17:19 | 26 |
kertio, если честно, ничего не понял : ) Постараюсь разобраться чуть позже.
Есть ли у тебя ссылка, где можно почитать о таком? Я раньше никогда fflush не использовал и все работа корректно. Подобных ошибок, как у меня, у кого-то ещё в google не нашел..[/QUOTE] На самом деле ничего сложно тут нет. ну вроде бы тут описано. http://itc.ua/forum/showthread.php?t=40057 Будут вопросы, постараюсь объяснить как смогу.
1
|
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
|
||||||
30.10.2012, 18:08 | 27 | |||||
Я вот об этом (2 вариант):
1
|
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
|
|
30.10.2012, 18:28 [ТС] | 28 |
alsav22, у меня подобная конструкция не приводит к порче записи.. Лишь к порче чтения :<
0
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
|
30.10.2012, 18:44 | 29 |
kertio, причем здесь ОС и кеширование HDD? Программа знать не знает, как происходят операции записи/чтения, она всего лишь делает запросы. ОС сама решает записывать данные сразу на диск сейчас или потом, для программы эти данные уже записаны.
nexen, про fflush:
1
|
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
|
|
30.10.2012, 19:54 | 30 |
На моём коде проверял? Среда какая?
Добавлено через 16 минут Я в Студии проверял и в Code Blocks. Разница только в том, что во втором варианте, в Code Blocks, не мусор, а пустота выводится, и в файле получается: 678пробелы678"
1
|
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
|
|
30.10.2012, 19:55 [ТС] | 31 |
alsav22, ага.
VS 2008.
0
|
26 / 26 / 3
Регистрация: 20.09.2011
Сообщений: 68
|
|
30.10.2012, 20:32 | 32 |
чуть чуть конечно не в тему, но все же,как тогда объяснить что на кешируемых фс если вырубить питание, то данные которые не были сброшены sync-ом, читай fflush-ем, теряются? тем более приводишь информацию по функции, и даже не потрудился перевести. после операции out поток должен быть сброшел, перед чтением. или я затупил где-то?
0
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
|
30.10.2012, 21:22 | 33 |
kertio, буфер потока и кеширование фс/диска разные вещи.
При вызове fflush, или при закрытии файла, данные должны записаться в файл на диске. ОС на свое усмотрение, или записывает сразу данные на диск, или оставляет их в кеше для последующей записи, если диск занят в данный момент другой операцией, все зависит как от самой ОС так и от драйвера устройства. Для программы эти данные уже записаны на носитель. И, естественно, если в тот момент, пока ОС держит данные в кеше, вырубить питание, то данные потеряются. Но повторюсь - для программы файл уже записан. Ну как бы тут люди не глупые, я думаю, английский технический язык знают, если занимаются программированием. Но могу перевести: В файлах, открытых для обновления ( открытых для записи и чтения одновременно ), поток ( тут наверно лучше было бы написать буфер потока ) должен быть сброшен после вывода ( записи в файл, в данном случае ) перед операцией ввода ( чтения из файла, в данном случае ). Как я понял, это синхронизирует потоки ввода и вывода. В C++, например, есть функция std::ios::tie для привязки потоков. Так, например, объект std::cin, по умолчанию, "привязан" к объекту std::cout, что гарантирует сброс буфера объекта std::cout перед попыткой ввода с помощью std::cin.
2
|
26 / 26 / 3
Регистрация: 20.09.2011
Сообщений: 68
|
|
31.10.2012, 07:16 | 34 |
так вроде бы об этом и шла речь... поэтому и не читаются данные правильно после операций: запись запись запись запись чтение... после записи нужно сделать, грубо говоря commit изменений, а потом читать. и перед тем как писать я прочитал об этой функции. полный справочник шилдта. там есть описание ф-ии.
PS, все равно спасибо. буду больше учить\читать.
1
|
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
|
|
31.10.2012, 20:25 | 35 |
Сейчас посмотрел, как это в линукс работает. Там и без fflush() всё корректно отрабатывает. Только после fflush() изменения (записанные) сразу в файле появляются, а если без, то после первой операции чтения (если в отладке смотреть, а скорее всего, перед первой операцией чтения). Наверное, в линукс синхронизация записи/чтения из файла сделана так же, как для cin/cout (как Toshkarik описывал в 33 посте).
1
|
31.10.2012, 20:25 | |
31.10.2012, 20:25 | |
Помогаю со студенческими работами здесь
35
Создать экземпляр метода класса или доступ к методу из экземпляра класса Как получить ссылку на текущий экземпляр класса внутри этого класса? Экземпляр класса как входные данные метода другого класса Создание указателя типа базового класса на экземпляр производного класса Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |