Как проверить, доступен ли ресурс PHP stream для чтения или записи?

в PHP, как проверить, является ли потоковый ресурс (или указатель файла, дескриптор или как вы хотите их назвать) читаемым или доступным для записи? Например, если вы столкнулись с ситуацией, когда вы ничего не знаете о том, как был открыт или создан ресурс, как вы проверяете, читаем ли он? И как вы проверяете, можно ли это записать?

на основе тестирования, которое я сделал (только с обычными текстовыми файлами с использованием PHP 5.3.3), fread() не бросает никаких ошибок в любом уровень, когда ресурс не читается. Он просто возвращает пустую строку, но он также делает это для пустого файла. И в идеале было бы лучше иметь чек, который не изменяет сам ресурс. Тестирование, если ресурс читается, пытаясь прочитать из него, изменит положение указателя.

наоборот, fwrite() не выдает никаких ошибок на любом уровне, когда ресурс не доступен для записи. Он просто возвращает ноль. Это немного полезнее, потому что если вы пытались записать определенное количество байтов в файл и fwrite() возвращает ноль, вы знаете, что что-то пошло не так. Но все же это не идеальный метод, потому что было бы намного лучше знать, можно ли его записать, прежде чем мне нужно будет писать ему, а не пытаться писать ему и видеть, если это не удастся.

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

это возможно? Существует ли что-нибудь подобное? Я не смог найти что-нибудь полезное. Заранее спасибо за ваши ответы.

2 ответов


довольно просто. Просто позвони stream_get_meta_data($resource) из вашего скрипта, затем проверьте mode элемент массива возвращаемого значения:

$f = fopen($file, 'r');
$meta = stream_get_meta_data($f);
var_dump($meta['mode']); // r

и если вы хотите знать, если базовые данные для записи:

var_dump(is_writable($meta['uri'])); // true if the file/uri is writable

хорошо, так что это может быть не лучшее решение, но я думаю, что этого достаточно, учитывая, что в PHP нет ничего, чтобы сделать это автоматически.

для первого шага вы получите индекс ресурса из файла, а затем прочтете имя файла:

$stat = fstat($fp);
$inode = $stat['ino'];
system("find -inum $inode", $result);

берется непосредственно из этот вопрос о поиске имени файла из filehandle.

теперь, когда у вас есть имя файла (в $result) можно сделать fileperms($result) на то, чтобы получить разрешения из.

отметим, что fileperms() возвращает int, и документация делает магию (фактически просто рассматривая int как восьмеричный) сохранения этого ведущего 0 (например, 0755).

Также обратите внимание, что документация делает волшебство преобразования, что int в строку типа -rw-r--r--