jstewmc / stream
逐字符流式读取非常大的文本文件或字符串
Requires (Dev)
- phpunit/phpunit: 4.2.*
README
Stream
一个多字节安全的流,用于逐字符读取非常大的文件(或字符串)。
将非常大的文件或字符串读入PHP内存并逐字符处理(如解析或词法分析)会很快耗尽进程内存。
这个库可以轻松、多字节、内存安全地流式传输非常大的文本文件的字符
use Jstewmc\Stream\Text; $characters = new Text('foo'); while (false !== $characters->current()) { echo "{$characters->current()}\n"; $characters->next(); }
上面的(简单)示例将产生以下输出
f
o
o
在后台,这个库使用 jstewmc/chunker 以多字节、低内存的方式将非常大的文本文件或字符串分块,并在必要时在这些块之间移动。
安装
这个库需要 PHP 7.4+。
它是多平台的,我们努力使其在Windows、Linux和OSX上运行效果相同。
应该通过 Composer 安装。要做到这一点,请将以下行添加到您的 composer.json
文件的 require
部分,并运行 composer update
{ "require": { "jstewmc/stream": "^0.4" } }
使用
实例化一个流
流可以实例化为 Text
或 File
use Jstewmc\Stream\{File, Text}; $textCharacters = new Text('foo'); $fileCharacters = new File('/path/to/file.txt');
默认情况下,流使用环境的字符编码和大约8kb的块大小。如果您需要更多控制,可以使用 Chunker
实例来实例化流,而不是使用字符串
use Jstewmc\{Chunker, Stream}; $textChunks = new Chunker\Text('foo', 'UTF-8', 16384 /* characters */); $textCharacters = new Stream\Text($textChunks); $fileChunks = new Chunker\File('/path/to/file.txt', 'UTF-8', 65536 /* bytes */); $fileCharacters = new Stream\File($fileChunks);
导航流
实例化流后,您可以使用 getCurrentCharacter()
、getNextCharacter()
和 getPreviousCharacter()
方法分别获取流的当前、下一个和前一个字符(这些方法分别别名为 current()
、next()
和 previous()
,并且如果字符不存在,它们将返回 false
)
use Jstewmc\Stream\Text; $characters = new Text('bar'); $characters->current(); // returns "b" $characters->next(); // returns "a" $characters->next(); // returns "r" $characters->next(); // returns false $characters->current(); // returns false $characters->previous(); // returns "r" $characters->previous(); // returns "a" $characters->previous(); // returns "b" $characters->previous(); // returns false $characters->current(); // returns false
这些方法通常会在 while
循环中组合使用
use Jstewmc\Stream\Text; $characters = new Text('bar'); while (false !== $characters->current()) { echo "{$characters->current()}\n"; $characters->next(); }
请注意,这些方法是 幂等的 和 可重复的。例如,您可以在流的末尾多次调用 next()
而不超出流的末尾,并且可以从流的末尾调用 previous()
来向相反方向导航。
提前查看
您可以使用 peek()
方法查看下一个 n 个字符,而不更新内部索引
use Jstewmc\Stream\Text; $characters = new Text('foo'); $characters->current(); // returns "f" $characters->peek(); // returns "o" $characters->peek(2); // returns "oo" $characters->peek(3); // returns "oo" $characters->current(); // returns "f"
测试内容
您可以使用 isOn()
方法测试流是否在字符串或包含数组中的字符串之一
use Jstewmc\Stream\Text; $characters = new Text('foo'); $characters->isOn('f'); // returns true (because the current character is "f") $characters->isOn('b'); // returns false $characters->isOn('foo'); // returns true $characters->isOn('bar'); // returns false $characters->isOn(['f', 'a', 'b']); // returns true (because "f" matches) $characters->isOn(['b', 'a', 'r']); // returns false $characters->isOn(['foo', 'bar', 'baz']); // returns true (because "foo" matches) $characters->isOn(['bar', 'baz', 'qux']); // returns false
您可以使用 isOnRegex()
方法测试是否有一些字符匹配给定的正则表达式(而不是尝试检测正则表达式中的字符数,这会非常困难,要搜索的字符数是第二个参数)
use Jstewmc\Stream\Text; $characters = new Text('foo'); $characters->isOnRegex('/f/'); // returns true $characters->isOnRegex('/b/'); // returns false $characters->isOnRegex('/foo/', 3); // returns true $characters->isOnRegex('/bar/', 3); // returns false
重置流
如果您需要,可以重置流的内部指针
use Jstewmc\Stream\Text; $characters = new Text('foo'); $characters->next(); // returns "o" $characters->reset(); $characters->current(); // returns "f"
许可
此库根据 MIT 许可证 发布。
贡献
欢迎贡献!
以下是一些入门步骤
# Clone the repository (assuming you have Git installed). ~/path/to $ git clone git@github.com:jstewmc/stream.git # Install dependencies (assuming you are using Composer locally). ~/path/to/stream $ php composer.phar install # Run the tests. ~/path/to/stream $ ./vendor/bin/phpunit # Create and checkout a new branch. ~/path/to/stream $ git checkout -b YOUR_BRANCH_NAME # Make your changes (be sure to add tests with 95%+ coverage and describe your # changes in the CHANGELOG's "Unreleased" section). # Run the tests. ~/path/to/stream $ ./vendor/bin/phpunit # Lint your changes. ~/path/to/stream $ ./vendor/bin/phpcs . # Automatically fix any issues that arise. ~/path/to/stream $ ./vendor/bin/phpcbf . # Push your changes to Github and create a pull request. ~/path/to/stream $ git push origin YOUR_BRANCH_NAME