Как считать последнюю строку из файла с

от admin

Прочитать последнюю строку текстового файла

Мне нужно знать, как читать последнюю строку текстового файла. Мне нужно найти строку, а затем обработать ее в базе данных SQL.
Я читал и просматривал Интернет, но я изо всех сил пытаюсь найти правильный способ сделать это. То есть:

  1. Найти последнюю строку файла.
  2. Обработать последнюю строку файла.

задан 24 июля ’12, 07:07

Что вы пробовали? Обратите внимание, что мы можем помочь только с «1». «2» полностью зависит от вас. — Marc Gravell

@DebbieDippenaar для очень больших файлов, которые может быть не плохой идеей. Лично я бы, наверное, прочитал буферы байтов за раз, и у вас будут серьезные проблемы с многобайтовыми кодировками, но. — Marc Gravell

6 ответы

Есть два пути: простой и неэффективный или ужасно сложный, но эффективный. Усложненная версия предполагает вменяемую кодировку.

Если ваш файл не so большой, что вы действительно не можете позволить себе прочитать все это, я бы просто использовал:

Обратите внимание, что здесь используется File.ReadLines , не File.ReadAllLines . Если вы используете .NET 3.5 или более раннюю версию, вам нужно будет использовать File.ReadAllLines или напишите свой код — ReadAllLines прочитает все файл в память за один раз, тогда как ReadLines транслирует это.

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

ответ дан 23 мая ’17, 12:05

Если вы знаете кодировку файла, вам не нужно справляться с большой неприятностью, если вы просто ищете последний разрыв строки, за которым следуют другие символы. Например, U+000D U+000A не будет иметь переменную длину в любой кодировке переменной длины, такой как UTF-8 или UTF-16. А все остальные, следующие за ним, обычно можно считать правильно сформированными. — Джо

@Joey: Хитрость заключается в том, что если вы ищете назад произвольное место в файле, вам нужно знать, что вы можете быть в середине персонажа. Не такая большая проблема для UTF-16, но в UTF-8 вам нужно выровнять себя по границе символа. и вы можете перейти в «\n» из «\r\n», так что у вас будет снова идти назад. В принципе, взгляните на код в связанном ответе. Если вы можете написать более простую версию, пожалуйста, мне было бы очень интересно ее увидеть. — Джон Скит

Я должен что-то упустить здесь. File.ReadLines возвращает System.Collections.Generic.IEnumerable объект, у которого нет метода «Последний», когда я пытаюсь его использовать. Мой код предназначен для платформы .NET 4.0. Мне не хватает какой-то ссылки на сборку или что-то еще? — дскарр

@dscarr: тебе не хватает using директива: using System.Linq; — Джон Скит

Помните о последствиях для производительности, используя это для больших файлов. — jjxtra

Он стримит строки и не загружает все в память, как File.ReadAllLines .

Создан 24 июля ’12, 08:07

как получить последний символ текстового файла?? — Нееля

@Neel Перейдя назад через последнюю строку, но на один символ. — Max

Создан 24 июля ’12, 08:07

ответ дан 15 окт ’13, 05:10

Примечание. Весь этот код предполагает использование UTF-8. Если вам нужно поддерживать кодовую страницу, которая использует символы двойной ширины, такие как Unicode, вам нужно добавить дополнительные проверки к символу до и/или после новой строки, чтобы убедиться, что это действительно новая строка.

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

Хорошая вещь в UTF-8 заключается в том, что когда вы нажимаете символ ‘\n’, вам не нужно беспокоиться о каких-либо зависимых байтах, потому что любой байт со сброшенным старшим битом в UTF8-8 является просто символом ASCII. Очень удобно!

Вы можете использовать решение в ‘Как читать текстовый файл обратно с помощью итератора в C #’, но имейте в виду, что код довольно сложный. Если вам просто нужен простой трейлер строки UTF-8, это решение будет работать очень хорошо и отлично работать даже с большими файлами журналов.

Если вы отслеживаете множество файлов одновременно и используете что-то вроде FileSystemWatcher в C#, этот прирост производительности будет очень важен. Я использую очень похожий код на дешевом Linux VPS с одним процессором, чтобы отслеживать ошибки входа в систему и помещать IP-адреса в брандмауэр в моем лицензированном MIT проекте. https://github.com/DigitalRuby/IPBan, С помощью https://github.com/DigitalRuby/IPBan/blob/master/IPBanCore/Core/Utility/LogFileScanner.cs (который обрабатывает несколько новых строк одновременно).

Вы будете удивлены тем, насколько большим может быть auth.log, когда ваш SSH-порт открыт для всех. Если вы регулярно читаете десятки или даже сотни файлов, вы будете очень рады, что не использовали File.ReadAllLines().Last();

Поскольку это всего лишь страница кода, это хороший баланс между простотой и очень быстрой работой.

Читать:
Windows 7 vl что это

Как прочитать последнюю строку файла с разделителями

У меня есть файл с разделителями с разделителями.
Я использую следующий код, чтобы прочитать последнюю строку. Я считаю, что цикл выполняется до последней строки и продолжает перезаписывать строку lastLine. Таким образом, как только последняя строка достигнута, цикл прерывается и строка становится последней строкой.

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

Решение

иначе вы не сможете получить последнюю строку.

ты можешь использовать

но нет смысла делать getline дважды

для лучшего разделителя в вашем случае я бы использовал специальный знак, скажем, do:

этот символ является знаком квадратного корня и, скорее всего, не будет использоваться в чате. Тем не менее, для каждого приходящего сообщения чата необходимо проверить, используется ли там знак, и если да, то удалить его. Теперь для каждого отправляемого сообщения отправьте его со знаком в конце, а при получении разделите на этот символ с помощью getline ,

таким образом, вы легко разделитесь в месте, которое, как вы знаете, пользователь не испортит.

Другие решения

Вы не объяснили, в чем ваша проблема, но я думаю, что она не проверяет каждую строку, потому что getline () внутри цикла указывает на следующий элемент, поэтому вы теряете половину ваших элементов.

Допустим, это ваши строки:

после первой итерации он переходит к:

3 .; <- (по внутренней линии getline)

Таким образом, вы теряете 2-й элемент. Петля продолжается и в конце

5 .; <- (по внутренней петле)

конец.; <- (by while): это назначает правую строку chuy и указывает на следующий элемент

который не существует и поэтому внутри getline () не работает

если файл не будет очень большим, вы можете сначала получить весь файл в строку и использовать string::find_last_of найти последний индекс точки с запятой. Затем выведите строку от этого индекса до конца файла.

Вывод последних K строк входного файла на C++

Можно действовать прямо — подсчитать количество строк (N) и вывести строки с N-K до N. Для этого понадобится дважды прочитать файл, что очень неэффективно. Давайте найдем решение, которое потребует прочитать файл только один раз и выведет последние K строк.

Можно создать массив для K строк и прочитать последние K строк. В нашем массиве там будут храниться строки от 1 до K, затем от 2 до K+1, затем от 3 до K+2 и т.д. Каждый раз, считывая новую строку, мы будем удалять самую старую строку из массива.

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

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

Пример использования закольцованного массива:

Приведенный далее код реализует этот алгоритм:

Мы считываем весь файл, но в памяти хранится только 10 строк.

Разбор взят из перевода книги Г. Лакман Макдауэлл и предназначен исключительно для ознакомления.
Если он вам понравился, то рекомендуем купить книгу «Карьера программиста. Как устроиться на работу в Google, Microsoft или другую ведущую IT-компанию».

Чтение с конца файла си

Здравствуйте. Буду краток. Вопрос заключается в том как наиболее эффективно произвести чтение последней строки из файла в си, чтобы не прогонять fscanf ом все строки файла а сразу считать последнюю строку? Заранее спасибо

Вячеслав161's user avatar

Если размер файла таков, что вариант «прогонять fscanf ом все строки файла» является чересчур расточительным, то остается только

  1. Открыть файл в бинарном режиме 1
  2. Завести буфер из N байтов
  3. В цикле вызовами fseek(. -(i * N), SEEK_END) (или fseek(. -N, SEEK_CUR) ) постепенно отступать назад от конца файла с шагом N
  4. Считывать из файла очередную порцию из N байтов в буфер
  5. Проверять буфер на предмет наличия в нем платформенно-зависимого 2 маркера конца строки

Таким образом вы сумеете найти ту позицию в файле, с которой начинается последняя строка и затем считать эту строку. Разумеется, можно сразу использовать переаллоцируемый буфер и постоянно накапливать читаемые в процессе поиска данные, ибо они являются частью искомой строки.

В качестве побочного замечания можно добавить, что формально стандартная библиотека С не обязана поддерживать позиционирование от конца файла ( SEEK_END ), т.е. с формально-абстрактной точки зрения «прогонять fscanf ом все строки файла» является единственным решением. Непонятно только, при чем здесь именно fscanf , а не более уместный fgets .

1 Стандартная библиотека С не поддерживает произвольного позиционирования в текстовых потоках

2 Так как файл открыт в бинарном режиме, трансляции платформенно-зависимого маркера конца строки в символ \n происходить не будет

Related Posts