| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Копирование из файла в файл |
| Автор: Metalex 14.4.2010, 14:57 | ||
| Здравствуйте! У меня проблема: из первого файла все содержимое должно копироватся во второй, первый очищается и в начало записывается строка, и затем все содержимое второго файла копируется в первый. +все это в функции. То есть произвотидся добавление строк в начало файла. Когда я открываю файл проверить, что в нем, там только последняя строка, остальных нет..
Благодарю за помощь! Добавлено через 13 минут и 46 секунд И еще вопрос: как скопировать из одного файла в другой все, кроме последней строки? |
| Автор: 17dufa 14.4.2010, 15:56 |
| Вы уверены, что Вам не в центр помощи? http://forum.vingrad.ru/Vingrad-help-center.html а реализация с копированием во второй файл - это по заданию? может исходным файлом обойтись (сдвиг вперед и запись в начала новой первой строки)? если все-таки копирование - не проще ли вызвать функцию ОС для копирования файла? |
| Автор: 17dufa 14.4.2010, 16:24 | ||
Metalex, что-то я того, не уверен. для памяти отработает. а вот для файлов... зависит от того, как работает файловый вывод - с конца или с начала, если с конца - получится, если с начала - фиг, ну или придется посимвольно с файлом работать. задача реализовать что-то наподобие:
для файлов можно попытаться открыть 2 потока на один файл - в одном считывать, в другом записывать, чуть меньше fseek-ов делать придеться. *Вы не ответили на вопрос - Вы уверены, что вам не в "Центр помощи"? |
| Автор: Metalex 14.4.2010, 16:27 |
| 17dufa, уверен. А уверен ли ты, что знаешь, что пишешь? Если не уверен, то лучше меня не путать, а то у меня еще все знания по файлам сырые |
| Автор: djamshud 14.4.2010, 16:31 |
| >Обьясните, пожалуйста, как это реализовать. Никак. Не сделать сдвиг данных файла. Только если лезть в глубины файловой системы. |
| Автор: Metalex 14.4.2010, 16:31 |
А если модеры посчитают нужным, они переместят, не беспокойся. Добавлено через 51 секунду djamshud, я об этом догадывался.. |
| Автор: djamshud 14.4.2010, 16:35 |
| >И еще вопрос: как скопировать из одного файла в другой все, кроме последней строки? Записывать в новый файл предыдущую строку после того, как прочитана следующая. Если следующей нет - не писать. Конкретно по коду ничего не подскажу, стримы люто не люблю. |
| Автор: ИванМ 14.4.2010, 16:39 |
| Metalex, т.е. как я понимаю нужно просто скопировать второй файл в начала первого? Сначала в на выходе в первом файле находится содержимое второго файла, а потом то что было в первом изначально? Если так, то можно скопировать первый файл в list, потом записать данные второго файл в первый и добавить содержимое листа туда же. Это делается буквально в нескольких строчках. |
| Автор: djamshud 14.4.2010, 16:46 |
| ИванМ, гигабайтовые файлы плачут по вашим идеям:). Временный файл - правильное решение. |
| Автор: Metalex 14.4.2010, 16:49 |
| ИванМ, 1) (то, где я писал код): у меня есть допустим сначала пустой файл. Мне нужно записать в него строку. При следующем вызове ф-ции в нее передается строка, которая помещается в файл перед тем, что там уже есть. 2) Как скопировать из одного файла в другой все, кроме последней строки? Если можно, то с кодом.. буду признателен. |
| Автор: 17dufa 14.4.2010, 16:50 | ||
djamshud, вот не надо грязи
удваивает первый символ в файле. допилить рашпилем до случая Metalex надеюсь возможно и если уж хотца второй файл - создать, записать новую строку, записать содержимое первого файла, первый файл удалить, второй переименовать. все полегче будет. как-то меня напрягает гонять весь хвост туда-сюда. |
| Автор: ИванМ 14.4.2010, 17:06 |
| djamshud, тоже глобально мыслите? |
| Автор: djamshud 14.4.2010, 17:09 |
| 17dufa, ну херню же написали. Взяли да перекопировали все данные в файле. Это не есть сдвиг. Кроме того, если произойдет sync записываемого файла, будет шляпа. Добавлено через 1 минуту и 29 секунд ИванМ, я просто стараюсь смотреть на ход вперед;). Никогда, никогда не читайте целиком файлы в память. |
| Автор: ИванМ 14.4.2010, 17:17 |
| djamshud, "никода не говори никогда" На самом деле вы, конечно, правы (на счет моего варианта). |
| Автор: 17dufa 14.4.2010, 17:25 |
| djamshud, однако. позвольте. что конкретно Вас не устраивает в данном сдвиге и почему это Вы лично к сдвигу не относите? повторюсь данный код из файла "123" делает файл "1123" по сути освобождая первый символ под запись. ужо рашпилем из этого сделал сдвиг на 2 байта. но выкладывать пока не буду. надо ж для начала понять, что ж такое сдвиг. |
| Автор: djamshud 14.4.2010, 17:34 | ||
| 17dufa, 1. Хороший сдвиг - это если бы вы открыли файл и просто приписали бы к нему в начало данные. Как делает обычный
только не в конец, а в начало. Так вот, так сделать по-простому нельзя. 2. Ваш код не работает. Причну я уже описал. |
| Автор: 17dufa 14.4.2010, 17:42 |
| djamshud, пункт 1 - эт я б сдвигом не назвал. так что не стоит бросаться громкими словами, для начала надо словари синхронизировать почему мой код не работает - можно по-подробней? |
| Автор: djamshud 14.4.2010, 20:19 | ||||||||||||||
| 17dufa, еще какой сдвиг - новые данные находятся перед старыми, хороший сдвиг - старые данные физически остались на прежнем месте, логически сдвинулись вперед. Ваш код плох: 1) сам по себе 2) медленный 3) не работает Было:
стало:
было:
стало:
было:
(в конце перенос строки, однобайтовый \n). стало:
(непечатаемые символы). в хексе:
Причину я уже называл выше. Было очень приятно поработать тестером. Счастливой отладки;). |
| Автор: 17dufa 15.4.2010, 12:28 | ||
| djamshud, я б назвал это вставкой, но не сдвигом. но эт вопрос терминологии. пусть будет сдвигом. для файлов такого сделать низя, так что придется обходиться "обычным" сдвигом или копированием. за работу спасибо, жаль она была проделана зря - приведенный код - не готовое решение, а некая отправная точка. в таком свете остается только пункт 2. так вот - медленный по сравнению с чем? и помниться Вы про sync говорили - что Вы имели в виду и как это отразиться на работе кода? вот результат небольшой доработки рашпилем:
вот этот вариант умудрился из "hello world" сделать "khello world" чего нет в этом варианте - если двигать на несколько символов (SHIFT_SIZE > 1) и размер файла не кратен SHIFT_SIZE будет жопа на последнем сдвиге, то есть когда двигается самое начало файла, думаю топикастер сможет допилить этот косяк. *по идее SHIFT_SIZE равен длине строки, которую надо вставить плюс длина "\n". |
| Автор: djamshud 15.4.2010, 14:54 | ||
| >за работу спасибо, жаль она была проделана зря Почему же зря? Вы привели код в более работоспособное состояние. Правда его адская арифметика нагоняет на меня тоску, разбирать его не хочу. >медленный по сравнению с чем? По сравнению с более верным решением, основанном на перемещении буферов и еще более годном - mmap-а файла и двигания его данных. Буфер вы уже сделали, но сами признаете, что работает не всегда. Mmap платформозависимое решение,.. Хотя в boost-е может быть и есть какие-нибудь кроссплатформенные костыли. С другой стороны, в данной задаче упор на скорость записи данных, поэтому буферизированное (буферы должны быть большими, Mb например) копирование не проиграет. >и помниться Вы про sync говорили - что Вы имели в виду и как это отразиться на работе кода? Была проблема сбоя стримов при сбросе данных на диск, который у меня происходил на каждой новой строке. Далее пример решения этой задачи при использовании mmap(в Linux). Примечателен простотой - отсутствием магических констант и безумных вычислений seek-ов.
|
| Автор: 17dufa 15.4.2010, 15:16 |
| djamshud, вариант еще вчерашний) родился из попыток сдвинуть более чем на 1 байт. и еще раз - я ни разу не старался написать готовый вариант, лишь предложить некий базис от которого можно отталкиваться ну и опровергнуть Ваш тезис, что подобное для файла невозможно в принципе. какая именно константа является магической? ну акромя имени файла? про перемещение буфера не понял. первый вариант двигал 1 байт, ну дык я вроде нигде не говорил, что если надо сдвинуть на 5 байт, то стоит вызвать тот код 5 раз мап файла на память и правда быстрей работает? проверяли? можно в цифрах? хотелось бы еще и сравнение расходов по памяти, ну чисто для полноты картины. |
| Автор: djamshud 15.4.2010, 16:18 | ||
| 17dufa, ну да, меня что-то перклинило на мысли, что вы хотели просто присоединить данные в начало файла. >какая именно константа является магической? ну акромя имени файла? Там дело не в магии оказалось, разобрал код, понял. >про перемещение буфера не понял. первый вариант двигал 1 байт, ну дык я вроде нигде не говорил, что если надо сдвинуть на 5 байт, то стоит вызвать тот код 5 раз Вы там весь файл побайтово двигали.
Да и сейчас у вас размер буфера пермещения равен самому сдвигу, то есть для сдвига файла на один байт все данные будут сдвигаться побайтово. В цифрах выигрыш мапа не скажу. На данной задаче он будет минимальным. Он очень существенен при чтении и обработки больших файлов. Накладные расходы памяти минимальны: операционная система просто предоставляет доступ к данным файла через механизм виртуальной памяти. В данном случае я просто показал более простой на мой взгял и почти рабочий способ решения задачи. Почти, потому что есть какое-то ограничение на размер файла для функции open, которое впрочем можно обойти. |
| Автор: 17dufa 15.4.2010, 17:02 |
| djamshud, да, согласен, размер сдвига равен размеру вставки. честно говоря не знаю, как сделать эти размеры разными, если тока ваять самодельные "кеши", но это уже другая задача. Ваш код на мапах изящнее, но вот будет ли выигрыш я лично не уверен, надо мерять и конкретно с цифирками сравнивать. насчет потенциальных тормозов в следствие того, что считывания из файла идут частые и мелкие: не знаю насчет линукса (хотя уверен, что там тоже самое), но винда точно "прозрачно" кеширует операции чтения/записи, так что реальные обращения к диску будут более рациональные, чем то, что написано в самом коде. хотя, канеш интересный вопрос как этот кеш работает со смещениями назад, так как уверен он более заточен под движение вперед. |
| Автор: djamshud 15.4.2010, 21:20 | ||
| 17dufa, Если первоначальная задача была "смотрите! я умею копировать данные внутри файла!", то да, задача другая;). Но что-то мне подсказывает, что вы хотели хорошенько их двинуть. Побайтовые обращения к файлу конечно кешируются, но дело то не только в дергании диска, а в принципе в огромном количества вызовов функции. И да, при обращении к файлу "задом наперед" эффективность кеширования может быть и просядет. Если хотите циферки, то доделайте свой вариант, и сравним, мне тоже интересно. Для завтравки вот небольшой тест сравнения побайтового чтения, буферизированного чтения (1Mb) и отражения файла в память. В качестве небольшой внешней нагрузки и проверки правильности работы методов решается задача поиска количества вхождения байта '1' в файл. Использовался видеофайл размером 1000Mb. Перед каждым измерением файловые буферы операционной системы сбрасывались. Побайтовое: Alg: byte, count: 4195218 Время выполнения 14.299s Программа занимала 64кб. Буферизированное: Alg: buf, count: 4195218 Время выполнения 1.632s Программа занимала 1064кб. Отображение в память: Alg: mmap, count: 4195218 Время выполнения 0.729s Программа занимала 64кб. Во втором тесте эксперементальным путем был найден еще и "идеальный" размер буфера - 8кб, при его использовании время сокращалось до 0.75с, т.е. в плотную приближалось к mmap. Это скорее всего уже тесно связано с типом и настройкой файловой системы, а то и аппаратными особенностями носителя информации.
|