Самый быстрый способ чтения содержимого файла

Хорошо, я ищу самый быстрый способ прочитать все содержимое файла через php с файловой дорожкой на сервере, также эти файлы могут быть огромными. Поэтому очень важно, чтобы он выполнял ТОЧНУЮ ТОЛЬКО к нему как можно быстрее.

Читает ли это по очереди быстрее, чем чтение всего содержимого? Хотя, я помню, что читал об этом, что чтение всего содержимого может привести к ошибкам для огромных файлов. Это правда?

Если вы хотите загрузить полное содержимое файла в переменную PHP, самым простым (и, возможно, самым быстрым) способом будет file_get_contents .

Но если вы работаете с большими файлами, загрузка всего файла в память может быть не такой хорошей идеей: вы, вероятно, закончите с ошибкой memory_limit , так как PHP не позволит вашему скрипту использовать больше, чем (обычно) пара мегабайт памяти.

Таким образом, даже если это не самое быстрое решение, чтение строки по строке ( fopen + fgets + fclose ) и работа с этими линиями «на лету», без необходимости загрузки всего файла в память, может быть необходимо …

file_get_contents() является наиболее оптимизированным способом чтения файлов на PHP, однако, поскольку вы читаете файлы в памяти, вы всегда ограничены объемом доступной памяти .

Вы можете выпустить ini_set('memory_limit', -1) если у вас есть права, но вы все равно будете ограничены объемом памяти, доступным в вашей системе, что является общим для всех языков программирования.

Единственное решение – прочитать файл в кусках , для этого вы можете использовать file_get_contents() с четвертым и пятым аргументами ( $offset и $maxlen – заданы в байтах ):

 string file_get_contents(string $filename[, bool $use_include_path = false[, resource $context[, int $offset = -1[, int $maxlen = -1]]]]) 

Вот пример, когда я использую этот метод для работы с большими файлами загрузки:

 public function Download($path, $speed = null) { if (is_file($path) === true) { set_time_limit(0); while (ob_get_level() > 0) { ob_end_clean(); } $size = sprintf('%u', filesize($path)); $speed = (is_int($speed) === true) ? $size : intval($speed) * 1024; header('Expires: 0'); header('Pragma: public'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Content-Type: application/octet-stream'); header('Content-Length: ' . $size); header('Content-Disposition: attachment; filename="' . basename($path) . '"'); header('Content-Transfer-Encoding: binary'); for ($i = 0; $i <= $size; $i = $i + $speed) { ph()->HTTP->Flush(file_get_contents($path, false, null, $i, $speed)); ph()->HTTP->Sleep(1); } exit(); } return false; } 

Другим вариантом является использование менее оптимизированных функций fopen() , feof() , fgets() и fclose() , особенно если вы хотите получить сразу все строки , вот еще один пример, который я представил в другом вопросе StackOverflow для импорта большого SQL запросов в базу данных :

 function SplitSQL($file, $delimiter = ';') { set_time_limit(0); if (is_file($file) === true) { $file = fopen($file, 'r'); if (is_resource($file) === true) { $query = array(); while (feof($file) === false) { $query[] = fgets($file); if (preg_match('~' . preg_quote($delimiter, '~') . '\s*$~iS', end($query)) === 1) { $query = trim(implode('', $query)); if (mysql_query($query) === false) { echo '<h3>ERROR: ' . $query . '</h3>' . "\n"; } else { echo '<h3>SUCCESS: ' . $query . '</h3>' . "\n"; } while (ob_get_level() > 0) { ob_end_flush(); } flush(); } if (is_string($query) === true) { $query = array(); } } return fclose($file); } } return false; } 

Какой метод вы используете, действительно будет зависеть от того, что вы пытаетесь сделать (как вы можете видеть с помощью функции импорта SQL и функции загрузки), но вам всегда придется читать данные в кусках .

 $file_handle = fopen("myfile", "r"); while (!feof($file_handle)) { $line = fgets($file_handle); echo $line; } fclose($file_handle); 
  1. Откройте файл и $file_handle файл $file_handle качестве ссылки на сам файл.
  2. Проверьте, находитесь ли вы уже в конце файла.
  3. Продолжайте читать файл до тех пор, пока вы не закончите, напечатайте каждую строку по мере ее чтения.
  4. Закройте файл.

Вы можете использовать file_get_contents

Пример:

 $homepage = file_get_contents('http://www.example.com/'); echo $homepage; 

Используйте fpassthru или readfile. Оба используют постоянную память с увеличением размера файла.

http://raditha.com/wiki/Readfile_vs_include

 foreach (new SplFileObject($filepath) as $lineNumber => $lineContent) { echo $lineNumber."==>".$lineContent; //process your operations here } 

Чтение всего файла за один раз происходит быстрее.

Но огромные файлы могут съесть всю вашу память и вызвать проблемы. Тогда ваша самая безопасная ставка – читать по строкам.

Если вы не беспокоитесь о размере памяти и файлах,

 $lines = file($path); 

$ lines – это массив файла.

Вы можете попробовать cURL ( http://php.net/manual/en/book.curl.php ).

Altho, вы можете проверить, у него есть свои ограничения

 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http://example.com/"); curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); $data = curl_exec ($ch); // Whole Page As String curl_close ($ch);