Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
1

Удалить строку из файла манипуляторами потока

27.05.2017, 18:46. Показов 1336. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Задача вроде проста - удалить из очень большого текстового файла строку, допустим последнюю. Так как в первую очередь надо обеспечить максимальную скорость/эффективность, то я решил воспользоваться простыми манипуляторами потока чтения/записи. Но как удалить саму строку из файла? Как обрезать часть файла с определенной позиции?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void pop_back_line(const std::string& filePath)
    {
        std::fstream fs(filePath, std::ios_base::out | std::ios_base::in | std::ios_base::ate);
        if (fs.is_open())
        {
            fs.seekg(-1, std::ios_base::end);
            int cur_pos = static_cast<int>(fs.tellg());
 
            while (fs.peek() != '\n')
            {
                fs.put(' ');
                fs.seekg(--cur_pos, std::ios_base::beg);
            }
        }
        else
            throw std::logic_error("erro openning file");
    }
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.05.2017, 18:46
Ответы с готовыми решениями:

Удалить строку из файла. Вставить строку из файла
Chao ;-) Задача: изменение файла БЕЗ СОЗДАНИЯ ДОПОЛНИТЕЛЬНОГО ФАЙЛА. Необходимо осуществить...

Удалить строку из файла
есть простенькакая функция записи в файлд и вывод строк из файла в цикле. нужно в каждом цикле...

Удалить строку из файла
Добрый день. Подскажите пожалуйста, как правильно удалить строку из файла. Я знаю номер строки (r)...

Удалить строку из файла
У меня есть файл test.txt: 4;fds;aaa;aaa;aaa; 1;bbb;bbb;bbb;bbb; 3;ttt;ttt;ttt;ttt; ...

15
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
27.05.2017, 20:45 2
Цитата Сообщение от notAll Посмотреть сообщение
Как обрезать часть файла с определенной позиции?
Никак. Переписывай в новый.

Добавлено через 4 минуты
Можно попробовать хак сделать. Имитировать, для текстового режима, конец файла: записать в нужном месте байт со значением 26 (0x1A).
0
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
28.05.2017, 01:15  [ТС] 3
Цитата Сообщение от nd2 Посмотреть сообщение
Никак. Переписывай в новый.
Нет, ну это не вариант, ради одной строки перегонять сотни мегабайт с одного места в другое.
Цитата Сообщение от nd2 Посмотреть сообщение
Имитировать, для текстового режима, конец файла: записать в нужном месте байт со значением 26 (0x1A).
Какие то крякозябры у меня выводит.
0
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
28.05.2017, 01:21  [ТС] 4
Кликните здесь для просмотра всего текста
Удалить строку из файла манипуляторами потока


Может какая то библиотека существует для таких задач - вставка и удаление строк для больших текстовых файлов?
0
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
28.05.2017, 01:24 5
Почему бы не использовать HEX редактор для этого? или IPS-патчер
там можно прописать скрипты и другие плюшки
0
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
28.05.2017, 01:27  [ТС] 6
eXPonent, решение нужно на С++.
0
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
28.05.2017, 01:37 7
Цитата Сообщение от notAll Посмотреть сообщение
Как обрезать часть файла с определенной позиции?
Если вы имеете ввиду удалить N последних/первых строк
то нужно просто при считывани N первых считать, остальные проигнорировать
или подсчитать кол-во строк в файле допустим M
а потом просто проигнорировать M-N первых строк, а остальные N считать и записать

Добавлено через 5 минут
С помощью обычной резалки-склейки файлов, можно реализовать реверс файла
т.е. поделить на строки, а потом склеить в обратном порядке, хотя тоже самое сделает и С++ но медленне как мне кажется, потому как в первых явно продуманное приложение (может работать и на ассемблере)
0
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
28.05.2017, 01:37  [ТС] 8
eXPonent, твое решение предполагает считывание всего объема файла в память, а затем его переписывания. Это не приемлемо в случае очень больших по размеру файлов. Такое решение не подходит.
0
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
28.05.2017, 01:54 9
Цитата Сообщение от notAll Посмотреть сообщение
решение нужно на С++
жаль, ведь некоторые языки могут поддерживать такую функцию вроде как PHP было

Добавлено через 2 минуты
Например можно попробовать вшить скрипт PHP выполнения в библиотечку
А из С++ уже запускать эту библиотечку, которая будет имитировать работу скрипта
конечно у тебя могут спросит как уже реализована библиотека, и тут проблема

Добавлено через 1 минуту
Цитата Сообщение от notAll Посмотреть сообщение
Это не приемлемо в случае очень больших по размеру файлов.
В случае если файл очень большой, то он обычно бъется по кластерам или секторам
в зависимости с чем быстрее работает железо, уже не вспомню

Добавлено через 47 секунд
А если скорость не важна, то можно бить по 2Гб

Добавлено через 9 минут
Чтобы избежать загрузки в память строк, которые всё равно будут проигнорированы и чтобы поддерживать произвольно большие входные строки, можно читать файл побайтно, используя fgetc().

Чтобы пропустить строки до тех пор пока не встретится строка, которая начинается с цифры (строка с численными данными), игнорируя возможные пробелы, можно использовать автомат с двумя состояниями:

1) читаем до тех пор пока не прочитан символ новой строки ('\n')
2) переходим в состояние ожидания цифры (expect_digit=1): все пробелы и табы игнорируются, если прочитана цифра, то возвращаем её назад в поток и выходим из функции, в противном случае (не цифра) возвращаемся в начальное состояние 1.


Аналогично и для позиции, можно считывая до endl и считать количество считываемых символов
(что бы не вызывать много раз функцию считывания строки)
0
зомбяк
1584 / 1218 / 345
Регистрация: 14.05.2017
Сообщений: 3,939
28.05.2017, 01:56 10
notAll, манипуляторы потока не дадут тебе выкинуть кусок файла. Непосредственно управлением файловой системы можно переписать расположение кусков файла на диске, но очень не уверен что это можно сделать для единичной строки (например у FAT32 можно манипулировать кусочками по 512 байт, а у NTFS - вовсе кусками не менее 8 МБ). Так что если у тебя строка окажется не кратной указанным длинам, или находиться в двух смежных секторах/томах, то удалить её не получится. И надо будет как минимум считать весь хвост файла и перезаписать его начиная с того места, где начиналась строка.
0
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
28.05.2017, 02:00 11
А можно посмотреть реализацию этих функций и самому написать похожие, но работающие уже без вызова
Так сказать ты их встроишь и обрежешь ненужный для тебя функционал

Добавлено через 2 минуты
Цитата Сообщение от TRam_ Посмотреть сообщение
а у NTFS - вовсе кусками не менее 8 МБ
вот вот, правильно говорит, т.е. максимум что ты сможешь сделать реально БЫСТРО так это реверс этих блоков
и чисто теоретически предположить, в каком блоке у тебя данные, а потом их считать
0
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
28.05.2017, 02:56 12
Цитата Сообщение от notAll Посмотреть сообщение
Какие то крякозябры у меня выводит.
Что по этому сообщению можно понять? Ни кода, ни что делал, ничего... Что хочешь - то и думай...
Цитата Сообщение от notAll Посмотреть сообщение
решение нужно на С++.
Встроенных способов для решения такой задачи, кроме перезаписи текстового файла, в С++ нет.
0
838 / 641 / 940
Регистрация: 26.06.2015
Сообщений: 1,409
28.05.2017, 04:56 13
Если для винды, то это легко решается WinAPI функцией SetEndOfFile, а установка позиции SetFilePointer/SetFilePointerEx
0
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
28.05.2017, 13:17  [ТС] 14
Цитата Сообщение от nd2 Посмотреть сообщение
Встроенных способов для решения такой задачи, кроме перезаписи текстового файла, в С++ нет.
Ну ясно.
Вот что нашел - int truncate(const char *, off_t); из unistd.h. Вроде отрезает корректно:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        std::fstream fs(filePath.c_str(), std::ios_base::in | std::ios_base::ate);
 
        if (fs.is_open())
        {
            fs.seekg(-1, std::ios_base::end);
            int cur_pos = static_cast<int>(fs.tellg());
 
            while (fs.peek() != '\n')
            {
                fs.seekg(--cur_pos, std::ios_base::beg);
            }
 
            fs.close();
            truncate(filePath.c_str(), --cur_pos);
        }
        else
            throw std::logic_error("error opening file");
0
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
28.05.2017, 15:39 15
Цитата Сообщение от notAll Посмотреть сообщение
int truncate(const char *, off_t); из unistd.h
Нестандарт. Студия уже не будет компилировать.
unistd.h
0
зомбяк
1584 / 1218 / 345
Регистрация: 14.05.2017
Сообщений: 3,939
28.05.2017, 15:44 16
Стандарт, но не С++, а POSIX.
0
28.05.2017, 15:44
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.05.2017, 15:44
Помогаю со студенческими работами здесь

Удалить строку из файла
Есть текстовый файл с содержанием: i я do делать go идти rain дождь Нужно сделать так, чтобы...

Удалить из файла строку
Как удалить определённую строку из файла. Вот код: string path = &quot;Data/data.txt&quot;; ...

Удалить из файла строку с номером k
помогите решить в формах. Дано число k и текстовый файл. Удалить из файла строку с номером k...

Удалить нужную строку из файла
День добрый как удалить нужную строку из файла? при этом не оставив после этого пустой строки??


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru