php - 在 ILIAS 中使用 Flysystem 附加到文件

标签 php flysystem ilias

我目前正在为某些插件编写一个记录器,在 ILIAS 中写入相当大的日志文件。我正在使用整洁的新文件系统。由于新的日志消息需要附加到文件中,我不能简单地使用 put 或 update,因为它们似乎总是截断日志文件。 Flysystem 似乎不支持简单的附加命令,因此我发现有效的一种方法如下:

$old_data = "";
if ($DIC->filesystem()->storage()->has($this->path)) {
    $old_data = $DIC->filesystem()->storage()->read($this->path);
}
$DIC->filesystem()->storage()->put($this->path, $old_data.$string);

但是,如果将大量数据附加到日志中,这对于 IO 来说似乎非常昂贵。我想,这最好使用流来完成。我在文档( https://github.com/ILIAS-eLearning/ILIAS/tree/release_5-3/src/Filesystem )中发现了以下内容:

$webDataRoot = $DIC->filesystem()->web();
$fileStream = $webDataRoot->readStream('relative/path/to/file');

//seek at the end of the stream
$fileStream->seek($fileStream->getSize() - 1);
//append something
$fileStream->write("something");

但是,这样我就得到了无法写入不可写流异常。看来我需要像这样打开流:

$resource = fopen('myPath', 'rw');

但是,文档中特别不鼓励这样做。通过使用 ILIAS 中的文件系统来解决这个问题的最佳方法是什么?

最佳答案

问题

ILIAS 的文件系统抽象利用 Flysystem 来操作文件系统。然而,正如您已经指出的,flysystem 没有提供将数据附加到文件的简单方法。主要原因似乎是,由于底层技术的原因,许多用于将文件写入存储后端的文件系统适配器不支持追加操作,例如 S3 V3 storage adapter它会重新上传整个文件。

不幸的是,位于( ILIAS-eLearning )的文档是错误的,因为某些文件系统适配器仅“模拟”文件流的行为,所以 Flysystem 返回的流是只读的。该流指向本地副本或内存中流,而不是位于存储后端的“真实”文件,请参阅Flysystem AWS S3 Adapter .

结论

总之,当前 ILIAS 文件系统实现没有正确的方法将数据附加到现有文件,因为 Flyway 不提供此类操作。 此外,即使flyway提供,一些存储后端仍然不支持此类操作。一个很好的例子是 AWS S3 存储后端,请参阅问题的答案 41783903 .

适合您的用例的可能解决方法

如果您能够使用多个日志文件,请使用某种日志文件轮换来减少 IO,这不是一个解决方案,但有助于将负载至少保持在一致的水平。例如,如果大小超过 20MB,则写入新的日志文件并保留最后 20 个日志文件。

关于php - 在 ILIAS 中使用 Flysystem 附加到文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51149062/

相关文章:

php - 使用 PEAR 的 Mail_Queue 时遇到问题

javascript - 如何在php中添加按钮而不是错误状态和成功消息?

php - 删除时找不到 Flysystem 文件

laravel - 如何在 Laravel 存储上启用 "reduced redundancy"

php - 内存限制耗尽 flysystem/src/Util/MimeType.php,如何找到文件路径?

php - 在自己的插件中获取所有 WooCommerce 产品

php - Elastic Beanstalk - 自定义 Nginx 配置文件 - PHP Web 应用程序

ilias - 开发 ILIAS 插件

ilias - 在 ilUIHookPluginGUI 中获取高级元数据的更简单方法?