From 53615ac0409281534b11bf4a714273787d34392a Mon Sep 17 00:00:00 2001 From: David Grudl Date: Wed, 25 Jan 2023 23:50:49 +0100 Subject: [PATCH] added FileSystem::readLines() [Closes #220] --- src/Utils/FileSystem.php | 31 ++++++++++++++++++++++++++ tests/Utils/FileSystem.readLines.phpt | 32 +++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 tests/Utils/FileSystem.readLines.phpt diff --git a/src/Utils/FileSystem.php b/src/Utils/FileSystem.php index 296175a64..a51539bec 100644 --- a/src/Utils/FileSystem.php +++ b/src/Utils/FileSystem.php @@ -176,6 +176,37 @@ public static function read(string $file): string } + /** + * Reads the file content line by line. Because it reads continuously as we iterate over the lines, + * it is possible to read files larger than the available memory. + * @return \Generator + * @throws Nette\IOException on error occurred + */ + public static function readLines(string $file, bool $stripNewLines = true): \Generator + { + return (function ($f) use ($file, $stripNewLines) { + $counter = 0; + do { + $line = Callback::invokeSafe('fgets', [$f], fn($error) => throw new Nette\IOException(sprintf( + "Unable to read file '%s'. %s", + self::normalizePath($file), + $error, + ))); + if ($line === false) { + fclose($f); + break; + } + if ($stripNewLines) { + $line = rtrim($line, "\r\n"); + } + + yield $counter++ => $line; + + } while (true); + })(static::open($file, 'r')); + } + + /** * Writes the string to a file. * @throws Nette\IOException on error occurred diff --git a/tests/Utils/FileSystem.readLines.phpt b/tests/Utils/FileSystem.readLines.phpt new file mode 100644 index 000000000..c1e7f80b9 --- /dev/null +++ b/tests/Utils/FileSystem.readLines.phpt @@ -0,0 +1,32 @@ + FileSystem::readLines('missing'), + Nette\IOException::class, + "Unable to open file 'missing'.%A%", +);