2015-07-09 3 views
0

в моем PHP проекта, я использую какой-то счетчик, который присоединяет к существующей (или новый файл) очень часто:Узнайте Еореп (..., «а») создан ли новый файл

$f = fopen($filename, 'ab'); 
fwrite($f); 
fclose($f); 

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

$existed = file_exists($filename); 
// Do the append 
$f = fopen($filename, 'ab'); 
fwrite($f); 
fclose($f); 
// Update permissions 
if (!$existed) { 
    @chmod($filename, 0666); 
} 

есть ли способ, чтобы выяснить, является ли «а» (присоединять) создал новый файл или добавленный к выходящему без использования file_exists()? Насколько я понимаю, file_exists() извлекает статистику файла, что приводит к ненужным накладным расходам по сравнению с простым файловым добавлением. Поскольку функция используется очень часто, мне интересно, есть ли возможность определить, создал ли fopen(..., 'a') новый файл без использования file_exists()?

Примечание: Это в основном вопрос стиля и интереса, а не настоящая проблема с производительностью. Но если я ошибаюсь, и fopen() уже получает статистику файла, пожалуйста, дайте мне знать!

Update

Хорошо, это действительно довольно академический вопрос. Вот некоторые тесты производительности, выполняемые в системе Windows (Apache, Win8.1 - без разрешений файлов UNIX) и Linux-машина (Nginx, Ubuntu 14.04, virutal machine).

Каждый тестовый прогон с 1000 повторениями, файл удаляется до первого повторения.

        Win Linux 
simply append one byte   1.8ms 9.4ms 
append + clearstatcache()   1.8ms 9.3ms 
test fileexists() + append  2.2ms 10.5ms 
fileexists() + append + clear  2.2ms 11.0ms 
append + chmod()     2.7ms 12.3ms 
append + fileexists() -> chmod() 3.3ms 10.6ms 

Примечание: последний из них использует и IF в пределах тестового цикла.

+0

http://php.net/manual/en/function.fopen.php – hek2mgl

ответ

2

РНР fopen это просто вызов LIBC fopen, которая автоматически создает файл для режимов w, w +, a и a +. Насколько я вижу, нет способа получить stat с битами разрешения из возвращаемого указателя файла.

Похоже, что PHP хранит массив stat для каждого открытого файла, и вы можете получить к нему доступ с помощью fstat($fp) с открытым файловым дескриптором $fp. Но поле mode содержит inode permission bits. Я не могу сразу увидеть, как «бит разрешения inode» связаны с «Режим файла UNIX». Системный вызов stat не использует этот термин.

Вы можете использовать режим «r +», чтобы открыть файл и создать его, если это не удается. Если нет, вам нужно ИСКАТЬ, чтобы затем закончить, чтобы достичь чего-то подобного.

Но, наконец, лучше всего проверить наличие, прежде чем открывать файл.

0

Нет, FOPEN просто возвращает ресурс, он не возвращает или установить флаг, указывающий, является ли уже существует файл - http://php.net/manual/en/function.fopen.php

+0

Я знаю - я скорее подумал о чем-то вроде 'ftell()' - но это не будет работать с файлом открыт для добавление только ... – BurninLeo

0

EDIT: см. Тест производительности в отредактированном вопросе.

Почему бы не позвонить chmod() раз?
Возможно, ваш file_exist() (возможно, небольшой тест производительности ...) более дорогой, чем chmod().

// Do the append 
$f = fopen($filename, 'ab'); 
fwrite($f); 
fclose($f); 
// Update persmissions 
@chmod($this->filename, 0666); 
+0

Хорошая идея - но ваша гипотеза не поддерживается тестом производительности, к которому я уже бежал :) – BurninLeo

+0

Я вижу это! :) Хороший тест. –

Смежные вопросы