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

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

  • автор:

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

Если файла нет, вы его создаёте (пустой!) и сразу же читаете из пустого файла. Не хватает записи в файл.

18 сен 2020 в 11:15

@V-Mor DirectoryPath ошибся в названии переменной, этот путь ведет к файлу. Исключение выбрасывается в строке с объявлением переменной lastLine

18 сен 2020 в 13:33
@AlexanderPetrov но ведь я использую метод LastOrDefault()
18 сен 2020 в 13:35

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

При вызове File.Create создаётся файловый поток, вы должны его закрыть, прежде чем опять открывать этот файл. У вас файл занят этим потоком. Пример из документации, где файловый поток закрывается автоматически с помощью using :

 using (FileStream fs = File.Create(path)) < byte[] info = new UTF8Encoding(true).GetBytes("This is some text in the file."); // Add some information to the file. fs.Write(info, 0, info.Length); >

Отслеживать
ответ дан 18 сен 2020 в 6:01
67.7k 5 5 золотых знаков 20 20 серебряных знаков 51 51 бронзовый знак

    Важное на Мете
Похожие

Подписаться на ленту

Лента вопроса

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.10.27.43697

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

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

Как добаватить текст в последнюю строку текстового файла
пересмотрел много в Гугле, подскажите пожалуйста,как добавить текст в первую строку текстового.

Удалить последнюю строку из файла и посчитать количество символов в тексте
Прочитали текст из файла и теперь нужно удалить последнюю строку и посчитать количество символов в.

Считать последнюю строку файла
Доброго времени суток! есть файл который имеет структуру(ниже), надо считать данные. До последней.

считать только последнюю строку из файла не обрабатывая другие
Можно как-то считать только последнюю строку из файла не обрабатывая другие. то-есть просто как-то.

Эксперт .NET

11809 / 8130 / 1241
Регистрация: 21.01.2016
Сообщений: 30,603

Крок, да возможно. Только это «вручную» делать придётся. Открываете поток файла, перематываете указатель позиции чтения в самый конец потока, потом читаете посимвольно данные в обратном порядке, к началу, пока не попадётся символ переноса строки (CRLF или просто LF), это и будет начало последней строки. Можно будет или данные ранее прочитанные «развернуть» или заново всё прочитать, но уже в сторону конца файла. Ну и сразу же после перемотки вы можете видеть символ переноса строки, так как последняя строка таким символом тоже может заканчиваться, его нужно будет проигнорировать.

Регистрация: 25.02.2017
Сообщений: 139
Спасибо, буду пробовать
557 / 534 / 225
Регистрация: 02.11.2016
Сообщений: 1,538

Крок, а string s = File.ReadAllLines(«»).Last(); Вам не подойдет? Или же Вам нужна именно последняя строка файла, без загрузки его в память?

Shogun31337, я вот прямо ожидал, что кто-нибудь такое предложит. 🙂

Меню пользователя @ Usaga

@ Shogun31337

Usaga, ну дык самое очевидное решение. 🙂

Меню пользователя @ Shogun31337

TheGreatCornholio
1252 / 730 / 285
Регистрация: 30.07.2015
Сообщений: 2,407

ЦитатаСообщение от Shogun31337 Посмотреть сообщение

ну дык самое очевидное решение

Количества слез, пролитого нормальными программистами при работе с чужим кодом, состоящим только из «очевидных»
и, находящихся на первых строках результата поиска решений, хватит на over9000 всемирных потопов 🙁

ЦитатаСообщение от Крок Посмотреть сообщение

Мне нужно в строку считать только последнюю строку.
Кликните здесь для просмотра всего текста

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; namespace MiscUtil.IO { /// /// Takes an encoding (defaulting to UTF-8) and a function which produces a seekable stream /// (or a filename for convenience) and yields lines from the end of the stream backwards. /// Only single byte encodings, and UTF-8 and Unicode, are supported. The stream /// returned by the function must be seekable. ///  public sealed class ReverseLineReader : IEnumerablestring> { /// /// Buffer size to use by default. Classes with internal access can specify /// a different buffer size - this is useful for testing. ///  private const int DefaultBufferSize = 4096; /// /// Means of creating a Stream to read from. ///  private readonly FuncStream> streamSource; /// /// Encoding to use when converting bytes to text ///  private readonly Encoding encoding; /// /// Size of buffer (in bytes) to read each time we read from the /// stream. This must be at least as big as the maximum number of /// bytes for a single character. ///  private readonly int bufferSize; /// /// Function which, when given a position within a file and a byte, states whether /// or not the byte represents the start of a character. ///  private Funclong,byte,bool> characterStartDetector; /// /// Creates a LineReader from a stream source. The delegate is only /// called when the enumerator is fetched. UTF-8 is used to decode /// the stream into text. ///  /// Data source public ReverseLineReader(FuncStream> streamSource) : this(streamSource, Encoding.UTF8) { } /// /// Creates a LineReader from a filename. The file is only opened /// (or even checked for existence) when the enumerator is fetched. /// UTF8 is used to decode the file into text. ///  /// File to read from public ReverseLineReader(string filename) : this(filename, Encoding.UTF8) { } /// /// Creates a LineReader from a filename. The file is only opened /// (or even checked for existence) when the enumerator is fetched. ///  /// File to read from /// Encoding to use to decode the file into text public ReverseLineReader(string filename, Encoding encoding) : this(() => File.OpenRead(filename), encoding) { } /// /// Creates a LineReader from a stream source. The delegate is only /// called when the enumerator is fetched. ///  /// Data source /// Encoding to use to decode the stream into text public ReverseLineReader(FuncStream> streamSource, Encoding encoding) : this(streamSource, encoding, DefaultBufferSize) { } internal ReverseLineReader(FuncStream> streamSource, Encoding encoding, int bufferSize) { this.streamSource = streamSource; this.encoding = encoding; this.bufferSize = bufferSize; if (encoding.IsSingleByte) { // For a single byte encoding, every byte is the start (and end) of a character characterStartDetector = (pos, data) => true; } else if (encoding is UnicodeEncoding) { // For UTF-16, even-numbered positions are the start of a character. // TODO: This assumes no surrogate pairs. More work required // to handle that. characterStartDetector = (pos, data) => (pos & 1) == 0; } else if (encoding is UTF8Encoding)  // For UTF-8, bytes with the top bit clear or the second bit set are the start of a character // See http://www.cl.cam.ac.uk/~mgk25/unicode.html characterStartDetector = (pos, data) => (data & 0x80) == 0  else { throw new ArgumentException("Only single byte, UTF-8 and Unicode encodings are permitted"); } } /// /// Returns the enumerator reading strings backwards. If this method discovers that /// the returned stream is either unreadable or unseekable, a NotSupportedException is thrown. ///  public IEnumeratorstring> GetEnumerator() { Stream stream = streamSource(); if (!stream.CanSeek) { stream.Dispose(); throw new NotSupportedException("Unable to seek within stream"); } if (!stream.CanRead) { stream.Dispose(); throw new NotSupportedException("Unable to read within stream"); } return GetEnumeratorImpl(stream); } private IEnumeratorstring> GetEnumeratorImpl(Stream stream) { try { long position = stream.Length; if (encoding is UnicodeEncoding && (position & 1) != 0) { throw new InvalidDataException("UTF-16 encoding provided, but stream has odd length."); } // Allow up to two bytes for data from the start of the previous // read which didn't quite make it as full characters byte[] buffer = new byte[bufferSize + 2]; char[] charBuffer = new char[encoding.GetMaxCharCount(buffer.Length)]; int leftOverData = 0; String previousEnd = null; // TextReader doesn't return an empty string if there's line break at the end // of the data. Therefore we don't return an empty string if it's our *first* // return. bool firstYield = true; // A line-feed at the start of the previous buffer means we need to swallow // the carriage-return at the end of this buffer - hence this needs declaring // way up here! bool swallowCarriageReturn = false; while (position > 0) { int bytesToRead = Math.Min(position > int.MaxValue ? bufferSize : (int)position, bufferSize); position -= bytesToRead; stream.Position = position; StreamUtil.ReadExactly(stream, buffer, bytesToRead); // If we haven't read a full buffer, but we had bytes left // over from before, copy them to the end of the buffer if (leftOverData > 0 && bytesToRead != bufferSize) { // Buffer.BlockCopy doesn't document its behaviour with respect // to overlapping data: we *might* just have read 7 bytes instead of // 8, and have two bytes to copy. Array.Copy(buffer, bufferSize, buffer, bytesToRead, leftOverData); } // We've now *effectively* read this much data. bytesToRead += leftOverData; int firstCharPosition = 0; while (!characterStartDetector(position + firstCharPosition, buffer[firstCharPosition]))  } leftOverData = firstCharPosition; int charsRead = encoding.GetChars(buffer, firstCharPosition, bytesToRead - firstCharPosition, charBuffer, 0); int endExclusive = charsRead; for (int i = charsRead - 1; i >= 0; i--) { char lookingAt = charBuffer[i]; if (swallowCarriageReturn) { swallowCarriageReturn = false; if (lookingAt == '\r') { endExclusive--; continue; } } // Anything non-line-breaking, just keep looking backwards if (lookingAt != '\n' && lookingAt != '\r') { continue; } // End of CRLF? Swallow the preceding CR if (lookingAt == '\n') { swallowCarriageReturn = true; } int start = i + 1; string bufferContents = new string(charBuffer, start, endExclusive - start); endExclusive = i; string stringToYield = previousEnd == null ? bufferContents : bufferContents + previousEnd; if (!firstYield || stringToYield.Length != 0) { yield return stringToYield; } firstYield = false; previousEnd = null; } previousEnd = endExclusive == 0 ? null : (new string(charBuffer, 0, endExclusive) + previousEnd); // If we didn't decode the start of the array, put it at the end for next time if (leftOverData != 0) { Buffer.BlockCopy(buffer, 0, buffer, bufferSize, leftOverData); } } if (leftOverData != 0) { // At the start of the final buffer, we had the end of another character. throw new InvalidDataException("Invalid UTF-8 data at start of stream"); } if (firstYield && string.IsNullOrEmpty(previousEnd)) { yield break; } yield return previousEnd ?? ""; } finally { stream.Dispose(); } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } } // StreamUtil.cs: public static class StreamUtil { public static void ReadExactly(Stream input, byte[] buffer, int bytesToRead) { int index = 0; while (index  bytesToRead) { int read = input.Read(buffer, index, bytesToRead - index); if (read == 0) { throw new EndOfStreamException (String.Format("End of stream reached with byte left to read.", bytesToRead - index, bytesToRead - index == 1 ? "s" : "")); } index += read; } } }

Как вывести последнюю строку из файла?

У меня есть файл «тест.txt» в нем есть 10 строк
Как сделать вывод последней строки?

  • Вопрос задан более трёх лет назад
  • 6645 просмотров

Комментировать

Решения вопроса 1

f_read = open("тест.txt", "r") last_line = f_read.readlines()[-1] print(last_line)

Ответ написан более трёх лет назад

Нравится 4 4 комментария

TheMergus @TheMergus Автор вопроса

Как удалить эту строку после вывода?

deepblack

deepblack @deepblack Куратор тега Python

TheMergus, вы отметьте решением ответ. Потом задавайте новый вопрос.

TheMergus @TheMergus Автор вопроса

TheMergus, Имелось ввиду задать новый вопрос не в комментариях, а принципиально новый вопрос создать. Ну да ладно.
Удалить последнюю строчку можно, например, так:

f = open("тест.txt", "r+") lines = f.readlines() lines = lines[:-1] f.seek(0) f.truncate() f.write("".join(lines))

Ответы на вопрос 0

Ваш ответ на вопрос

Войдите, чтобы написать ответ

python

  • Python
  • +1 ещё

Почему при большом количестве строк async выдает ошибку?

  • 1 подписчик
  • 5 часов назад
  • 35 просмотров

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

Покинул форум
Сообщений всего: 3
Дата рег-ции: Февр. 2013

Помог: 0 раз(а)

Каждый час формируется TXT файл с метеоданными и ложится в папку

Никак не пойму как считать именно последнюю строку из этого файла для последующего вывода пользователям

CODE (text):
скопировать код в буфер обмена
2013-02-08 04:10:24,30,19,28.3,86,-4.4,1023.3,1.7,2.7,2,27.0,0
2013-02-08 04:40:24,30,18,28.3,85,-3.9,1023.3,0.3,1.0,5,27.0,0
2013-02-08 05:10:24,30,18,28.4,85,-3.4,1023.4,1.0,2.0,2,27.0,0
2013-02-08 05:40:24,30,19,28.5,83,-3.0,1023.6,0.3,1.4,14,27.0,0
2013-02-08 06:10:25,30,21,28.8,82,-2.6,1023.9,0.7,1.4,0,27.0,0
# выбираем файл последнего дня

$filename = ( «/server/test.dom14.com/weather/data/raw/» ) . ( date ( «Y» ) ) . ( «/» ) . ( date ( «Y-m» ) ) . ( «/» ) . ( date ( «Y-m-d» ) ) . ( «.txt» ) ;

$f = fopen ( » $filename » , «r» ) ;
while ( ! feof ( $f ) )
$outString = fgets ( $f ) ;
$arrT = explode ( «,» , fgets ( $f ) ) ;

echo «Дата: » . $arrT [ 0 ] . » Температура » . $arrT [ 5 ] . » Скорость ветра » . $arrT [ 8 ] . «м/с» , «
» ;

(Отредактировано автором: 08 Февраля, 2013 — 08:45:41)

Отправлено: 08 Февраля, 2013 — 08:50:47

Покинул форум
Сообщений всего: 7190
Дата рег-ции: Февр. 2012

Помог: 353 раз(а)

$filename = ( «/server/test.dom14.com/weather/data/raw/» ) . ( date ( «Y» ) ) . ( «/» ) . ( date ( «Y-m» ) ) . ( «/» ) . ( date ( «Y-m-d» ) ) . ( «.txt» ) ;

$c = file ( $filename ) ;
$arrT = explode ( «,» , $d ) ;

echo «Дата: » . $arrT [ 0 ] . » Температура » . $arrT [ 5 ] . » Скорость ветра » . $arrT [ 8 ] . «м/с» , «
» ;

——
Чем больше узнаю, тем больше я не знаю.

Отправлено: 08 Февраля, 2013 — 08:52:17

Покинул форум
Сообщений всего: 48
Дата рег-ции: Окт. 2012

Помог: 3 раз(а)

if ( file_exists ( $filename ) && is_readable ( $filename ) ) {
$array = file ( $filename ) ;
$last_elem = count ( $array ) — 1 ;
echo $array [ $last_elem ] ;

DelphinPRO
И правда, так проще

(Отредактировано автором: 08 Февраля, 2013 — 08:53:51)

Отправлено: 08 Февраля, 2013 — 09:13:59

Покинул форум
Сообщений всего: 3
Дата рег-ции: Февр. 2013

Помог: 0 раз(а)

Спасибо большое!
Отправлено: 08 Февраля, 2013 — 10:27:10

Покинул форум
Сообщений всего: 7190
Дата рег-ции: Февр. 2012

Помог: 353 раз(а)

thesameson пишет:
И правда, так проще

разумеется. В первую очередь нужно посмотреть нет ли стандартной функции для решения задачи, а уже потом придумывать свои алгоритмы. В данном случае — один вызов array_pop .

Правда, следует учитывать, что файл будет считываться полностью в память. Гиговые файлы так открывать не следует

——
Чем больше узнаю, тем больше я не знаю.

Отправлено: 08 Февраля, 2013 — 11:29:01

Рекордсмен по количеству сообщений за 7 дней

Покинул форум
Сообщений всего: 2133
Дата рег-ции: Дек. 2008
Откуда: Москваль

Помог: 52 раз(а)

Скрипт, который описан выше, копирует ВЕСЬ файл в массив (представляем, что происходит при работе с большими файлами), потом берет лишь последний элемент огромного массива.

Как это делают обычно:

Если файлы не сильно большие — не заморачиваться, а в цикле получаем содержимое файла построчно (http://www.php.net/manual/en/function.fgets.php) все непоследние строки пропускаем, последнюю оставляем. Чем это лучше вышеописанного варианта? — тем, что нет огромного массива с содержанием всего файла, а есть лишь переменная, содержащая лишь одну строчку из файла

Если файл сильно большой — вам поможет функция http://www.php.net/manual/en/function.fseek.php . в комментариях много полезного, например http://www.php.net/manual/en/fun. fseek.php#106336
Что делает этот код? Смотрит размер файла, перемещает указатель в самый конец и в цикле посимвольно идет к началу, пока не натыкается на перевод строки. То, что между концом файла и первым переводом строки — это и есть последняя строка, но в обратном порядке.
(Добавление)
Что бы обратную строку перевести к нормальному виду — используйте http://www.php.net/manual/en/function.strrev.php

Отправлено: 08 Февраля, 2013 — 11:33:10

Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007
Откуда: Berlin

Помог: 707 раз(а)

А для ленивых есть shell_exec + tail

——
Есть в мире две бесконечные вещи — это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.

Отправлено: 08 Февраля, 2013 — 21:55:39

Покинул форум
Сообщений всего: 3
Дата рег-ции: Февр. 2013

Помог: 0 раз(а)

Ребяты всем спасибо, конечный результат ясен и понятно куда копать!
Далее думаю еще с столкнусь с проблемами и сразу отпишусь в другой теме
Темку можно закрывать

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *