Добавить в файл, используя 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);

Однако в отношении ввода-вывода это выглядит очень дорого, если в журнал добавляются огромные объемы данных. Я думаю, это лучше всего сделать с помощью потоков. В документации ( 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");

Тем не менее, с этим я получаю Can not write для исключения для записи потока. Кажется, мне нужно открыть поток так:

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

Однако это специально не рекомендуется в документах. Каков наилучший способ справиться с этим, используя файловую систему в ILIAS?

1 ответ

Решение

проблема

Абстракция файловой системы ILIAS использует flysystem для управления файловой системой. Однако, как вы уже отметили, flysystem не предоставляет простого способа добавления данных в файлы. Основной причиной, по-видимому, является тот факт, что многие из адаптеров файловой системы, которые используются для записи файла в серверную часть хранилища, не поддерживают операцию добавления из-за базовой технологии, например адаптер хранения S3 V3, который повторно загружает весь файл,

К сожалению, документация, расположенная по адресу ( http://(https://github.com/ILIAS-eLearning/ILIAS/tree/release_5-3/src/Filesystem), неверна, поскольку потоки, возвращаемые flysystem, читаются только из-за того, что некоторые адаптеры файловой системы только "подражать" поведению файлового потока. Поток указывает на локальную копию или поток в памяти вместо "реального" файла, расположенного на внутренней стороне хранилища, см. Flysystem AWS S3 Adapter.

Заключение

В заключение, нет правильного способа добавить данные в существующий файл с текущей реализацией файловой системы ILIAS, потому что flyway не предоставляет такой операции. Кроме того, некоторые бэкэнды хранилища по-прежнему не будут поддерживать такие операции, даже если их предоставит пролет. Хорошим примером является сервер хранения AWS S3, см. Ответ на вопрос 41783903.

Возможное решение для вашего варианта использования

Если вы можете использовать несколько файлов журнала, используйте своего рода ротацию файлов журнала, чтобы уменьшить количество операций ввода-вывода, что не является решением, но помогает поддерживать нагрузку как минимум на постоянном уровне. Например, запишите новый файл журнала, если его размер превысит 20 МБ, и сохраните последние 20 файлов журнала.

Другие вопросы по тегам